/*
 * Copyright (c) 2025 Industrial Software Feature Database
 */
package com.comac.ins.isfd.service.impl;

import cn.hutool.core.date.DateTime;
import cn.hutool.json.XML;
import com.anwen.mongo.model.PageResult;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.comac.ins.common.core.constant.CommonConstant;
import com.comac.ins.common.core.domain.model.LoginUser;
import com.comac.ins.common.core.exception.base.BaseException;
import com.comac.ins.common.core.utils.MapstructUtils;
import com.comac.ins.common.mybatis.core.page.PageQuery;
import com.comac.ins.common.mybatis.core.page.TableDataInfo;
import com.comac.ins.common.oss.entity.UploadResult;
import com.comac.ins.common.satoken.utils.LoginHelper;
import com.comac.ins.isfd.constant.enums.*;
import com.comac.ins.isfd.domain.IsfdDatabaseDataAttachImportResult;
import com.comac.ins.isfd.domain.IsfdDatabaseExistDataInfo;
import com.comac.ins.isfd.domain.IsfdDatabaseModelConfig;
import com.comac.ins.isfd.domain.IsfdDatabaseMongoQuery;
import com.comac.ins.isfd.domain.bo.*;
import com.comac.ins.isfd.domain.bo.query.IsfdDatabaseDataImportRecordQueryBo;
import com.comac.ins.isfd.domain.vo.*;
import com.comac.ins.isfd.mapper.IsfdDatabaseModelConfigMapper;
import com.comac.ins.isfd.service.*;
import com.comac.ins.isfd.util.ExcelUtils;
import com.comac.ins.isfd.util.ImportDataFileStorageUtil;
import com.comac.ins.system.service.ISysDictDataService;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.bson.Document;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 数据库建模配置Service业务层处理
 *
 * @author Lion Li
 * @date 2024-11-27
 */
@RequiredArgsConstructor
@Service
@Slf4j
public class IsfdDatabaseDataManagementServiceImpl implements IIsfdDatabaseDataManagementService {

    @Autowired
    private final IIsfdBusinessDatabaseRefService businessDatabaseRefService;

    @Autowired
    private final ISysDictDataService iSysDictDataService;

    @Autowired
    private final ImportDataFileStorageUtil importDataFileStorageUtil;

    @Autowired
    private IsfdDatabaseModelConfigMapper baseMapper;

    @Autowired
    private IIsfdDatabaseModelConfigService configService;

    @Autowired
    private IIsfdDatabaseMongoService mongoService;

    @Autowired
    private IIsfdDatabaseDataImportRecordService importRecordService;

    @Autowired
    private IIsfdAlgorithmConfigService isfdAlgorithmConfigService;

    @Override
    public IsfdDatabaseDataImportRecordVo queryRecordVoById(Long recordId) {
        return importRecordService.queryById(recordId);
    }

    @Override
    public TableDataInfo<IsfdDatabaseDataImportRecordListVo> queryPageList(IsfdDatabaseDataImportRecordQueryBo queryBo) {
        return importRecordService.queryPageList(queryBo);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean importXMLData(IsfdDatabaseDataImportXMLBo bo, MultipartFile file) {
        // 获取数据
        Map<String, Object> xmlMap = convertXmlFileToMap(file);
        Integer depth = bo.getDepth();
        // 平铺数据
        List<Map<String, Object>> dataList = getDataAtDepth(xmlMap, 0, depth);
        // 匹配模型，获取字段列表
        List<IsfdDatabaseModelConfigTableVo> fieldTableList = configService.getFieldTableList(bo.getModelId());
        // 转换为有结构的json数据
        List<Map<String, Object>> nestedJsonDataList = new ArrayList<>();
        for (Map<String, Object> dataMap : dataList) {
            Map<String, Object> nestedJsonData = buildNestedJsonData(dataMap, fieldTableList);
            nestedJsonDataList.add(nestedJsonData);
        }

        // 创建临时文件路径
        Path targetDir = createTargetDir(bo.getTableName());

        // 如果通过校验, 保存文件
        IsfdDatabaseDataValidatedDataVo validatedDataVo = checkImportDataList(bo.getModelId(), null, nestedJsonDataList, targetDir);

        if (validatedDataVo.getTotalDataCount() == 0 ) {
            throw new BaseException("数据为空！");
        }

        List<Map<String, List<Map<String, Object>>>> validatedData = validatedDataVo.getValidatedData();

        String directoryPath = null;
        if (validatedDataVo.getFailedDataCount() > 0) {
            throw new BaseException("数据检查失败！message: " + validatedDataVo.getFailedMessage());
        }

        // 保存
        directoryPath = importDataFileStorageUtil.saveToDisk(targetDir, validatedData, file);


        // 生成导入记录
        IsfdDatabaseDataImportRecordBo recordBo = MapstructUtils.convert(bo, IsfdDatabaseDataImportRecordBo.class);
        recordBo.setImportMethod(IsfdImportMethodEnum.XML.getDesc());

        // 从磁盘获取数据
        Map<String, Object> cachedData = importDataFileStorageUtil.getFromDisk(directoryPath);
        List<String> filePaths =
            (List<String>) cachedData.getOrDefault("filePaths", new ArrayList<>());
        if (CollectionUtils.isEmpty(filePaths) || CollectionUtils.isEmpty(validatedData)) {
            throw new BaseException("未找到数据！path: " + directoryPath);
        }

        // 保存场景/系统/模型关联关系
        Long refId = updateBusinessDatabaseRef(recordBo);
        recordBo.setBusinessDatabaseRefId(refId);

        recordBo.setDataQuantity(validatedData.size());
        recordBo.setDataFileUrl(String.join(",", filePaths));
        recordBo.setFileName(String.join(",", filePaths.stream().map(filePath -> new File(filePath).getName()).toList()));
        recordBo.setTableName(String.join(",",validatedData.get(0).keySet()));

        recordBo.setDataImportTime(new DateTime());
        recordBo.setFileName(Path.of(filePaths.get(0)).getFileName().toString());
        LoginUser loginUser = LoginHelper.getLoginUser();
        recordBo.setDataImportBy(loginUser.getUserId().toString());
        recordBo.setFileSize(file.getSize());

        // 找到导入的主表
        IsfdDatabaseModelConfig config = baseMapper.selectById(recordBo.getModelId());
        if (config == null) {
            throw new BaseException("没有找到模型");
        }
        String mainTableName = config.getTableName();

        // 转换数据
        Map<String, List<Map<String, Object>>> transformedData = transformValidatedDataStructure(validatedData);

        // 统计数据量
        Map<String, Integer> tableDataSizeMap =  transformedData.entrySet().stream()
            .filter(entry -> entry.getValue() != null && !entry.getValue().isEmpty()) // 过滤掉 null 和空 list
            .collect(Collectors.toMap(
                Map.Entry::getKey,
                entry -> entry.getValue().size()
            ));

        // 生成导入记录
        IsfdDatabaseDataImportRecordBo importRecordBo = importRecordService.createImportRecord(recordBo, IsfdImportMethodEnum.JSON, mainTableName, tableDataSizeMap, LoginHelper.getLoginUser());

        // 将导入记录记入数据，并重构数据
        IsfdDatabaseDataMongoImportRecordBo mongoImportRecord = IsfdDatabaseDataMongoImportRecordBo.createMongoImportRecord(importRecordBo);

        // 获取数据变更并添加导入记录
        List<IsfdDatabaseDataAttachImportResult> dataChangeResult = attachImportRecords(transformedData, null, mongoImportRecord);

        // 导入数据
        Map<String, List<Map<String, Object>>> finalData = new HashMap<>();
        for (IsfdDatabaseDataAttachImportResult data : dataChangeResult) {
            finalData.put(data.getTableName(), data.getData()); // 这里提取每个表对应的数据列表
        }
        importData(finalData, mongoImportRecord, null, recordBo.getModelId());

        return true;
    }

    public List<Map<String, Object>> getDataAtDepth(Map<String, Object> currentMap, int depth, int targetDepth) {
        List<Map<String, Object>> result = new ArrayList<>();
        // 递归查找指定深度的数据
        findDataRecursively(currentMap, result, depth, targetDepth);
        if (CollectionUtils.isEmpty(result)) {
            throw new BaseException("未解析出XML数据！");
        }
        return result;
    }

    private void findDataRecursively(Object current, List<Map<String, Object>> result, int currentDepth, int targetDepth) {
        // 达到目标深度，收集数据
        if (currentDepth == targetDepth) {
            if (current instanceof Map) {
                result.add((Map<String, Object>) current);
            }
            return;
        }
        // 如果当前对象是Map，继续递归
        if (current instanceof Map) {
            for (Object value : ((Map<String, Object>) current).values()) {
                findDataRecursively(value, result, currentDepth + 1, targetDepth);
            }
        }
        // 如果当前对象是List，继续递归
        else if (current instanceof List) {
            for (Object item : (List<?>) current) {
                findDataRecursively(item, result, currentDepth + 1, targetDepth);
            }
        }
    }

    private static Map<String, Object> convertXmlFileToMap(MultipartFile file) {
        // 将MultipartFile内容转换为字符串
        try {
            String xmlContent = new String(file.getBytes(), "UTF-8");
            // 使用Hutool的XML类将XML字符串转换为Map
            return XML.toJSONObject(xmlContent).toBean(Map.class);
        } catch (IOException e) {
            throw new BaseException("XML文件读取失败！");
        }
    }

    private Map<String, Object> buildNestedJsonData(Map<String, Object> data, List<IsfdDatabaseModelConfigTableVo> fieldTableList) {
        // 找到主模型
        IsfdDatabaseModelConfigTableVo mainTableVo = fieldTableList.stream().filter(
            vo -> vo.getParentTableName() == null
        ).findFirst().orElse(null);
        if (mainTableVo == null) {
            throw new BaseException("未找到主模型！");
        }
        // 构造结构化数据
        return buildSubJsonDataRecursively(data, mainTableVo, fieldTableList);
    }

    private Map<String, Object> buildSubJsonDataRecursively(Map<String, Object> data, IsfdDatabaseModelConfigTableVo fieldTableVo, List<IsfdDatabaseModelConfigTableVo> fieldTableList) {
        // 构造结构化数据
        Map<String, Object> nestedJsonData = new HashMap<>();
        List<IsfdDatabaseModelConfigFieldVo> fieldVoList = fieldTableVo.getFieldVoList();
        for (IsfdDatabaseModelConfigFieldVo fieldVo : fieldVoList) {
            String fieldName = fieldVo.getFieldName();
            Object value;
            // 判断是否有子模型
            IsfdDatabaseModelConfigTableVo relatedTableVo = fieldTableList.stream()
                .filter(vo ->
                    Objects.equals(vo.getParentTableName(), fieldTableVo.getTableName()) &&
                        Objects.equals(vo.getParentFieldName(), fieldName)
                ).findFirst().orElse(null);

            if (relatedTableVo != null) {
                value = buildSubJsonDataRecursively(data, relatedTableVo, fieldTableList);
            }

            // 判断是否有嵌套对象
            else if (!CollectionUtils.isEmpty(fieldVo.getFieldList())) {
                value = buildSubJsonDataRecursively(data, fieldVo.getFieldList());
            }

            else {
                value = data.get(fieldName);
            }

            nestedJsonData.put(fieldName, value);
        }

        return nestedJsonData;
    }

    private Map<String, Object> buildSubJsonDataRecursively(Map<String, Object> data, List<IsfdDatabaseModelConfigFieldVo> fieldVoList) {
        Map<String, Object> nestedJsonData = new HashMap<>();
        for (IsfdDatabaseModelConfigFieldVo fieldVo : fieldVoList) {
            String fieldName = fieldVo.getFieldName();
            Object value;
            if (!CollectionUtils.isEmpty(fieldVo.getFieldList())) {
                value = buildSubJsonDataRecursively(data, fieldVo.getFieldList());
            }
            else {
                value = data.get(fieldName);
            }
            nestedJsonData.put(fieldName, value);
        }

        return nestedJsonData;
    }

    @Override
    public Path createTargetDir(String tableName) {
        String basePrefix = iSysDictDataService.selectDictValueByTypeAndLabel(
            CommonConstant.SYS_COMMON_DICT_TYPE,
            CommonConstant.IMPORT_DATA_STORAGE_PREFIX
        );
        String uniqueDirName = java.time.LocalDateTime.now().format(java.time.format.DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
        return Paths.get(basePrefix, tableName, uniqueDirName);
    }


    /**
     * 检查数据完整性
     */
    @Override
    public IsfdDatabaseDataImportCheckVo checkAndCacheImportData(Long modelId, String parentId, String importMethod, MultipartFile file) {
        // 创建临时文件路径
        IsfdDatabaseModelConfig rootConfig = configService.queryByIdReturnTopParent(modelId);
        if (rootConfig == null) {
            throw new BaseException("没有找到根模型！modelId: "  + modelId);
        }
        String rootTableName = rootConfig.getTableName();
        Path targetDir = createTargetDir(rootTableName);
        Path filesDir = targetDir.resolve("files");
        List<Map<String, Object>> dataList = null;
        if (IsfdImportMethodEnum.EXCEL.getDesc().equals(importMethod)) {
            try {
                dataList = ExcelUtils.convertExcelFileToDataList(file);
            } catch (IOException e) {
                log.error("Excel文件读取失败", e);
                throw new BaseException("Excel文件读取失败");
            }
        } else if (IsfdImportMethodEnum.COMPRESSED.getDesc().equals(importMethod)){
            try {
                Path uploadDir = importDataFileStorageUtil.unzipFileToTempDir(file, targetDir);
                // 处理数据列表
                dataList = new ArrayList<>(importDataFileStorageUtil.convertJsonFileToDataList(uploadDir));
            } catch (IOException e) {
                log.error("ZIP文件解压失败", e);
                throw new BaseException("ZIP文件解压失败，error:" + e.getMessage());
            }

        } else if (IsfdImportMethodEnum.JSON.getDesc().equals(importMethod)){
            dataList = new ArrayList<>(importDataFileStorageUtil.convertJsonFileToDataList(file));
        } else {
            throw new BaseException("不支持的导入方式：" + importMethod);
        }

        // 检查数据
        IsfdDatabaseDataValidatedDataVo validatedDataVo = checkImportDataList(modelId, parentId, dataList, filesDir);
        int totalDataCount = validatedDataVo.getTotalDataCount();
        int qualifiedDataCount = validatedDataVo.getQualifiedDataCount();
        int failedDataCount = validatedDataVo.getFailedDataCount();
        List<Map<String, String>> failedMessage = validatedDataVo.getFailedMessage();

        List<Map<String, List<Map<String, Object>>>> validatedDataList = validatedDataVo.getValidatedData();

        // 如果通过校验, 保存文件
        long fileSize = 0;
        if (file != null && !file.isEmpty()) {
            fileSize = file.getSize();
        }
        String directoryPath = null;
        if (failedDataCount == 0) {
            try {
                directoryPath = importDataFileStorageUtil.saveToDisk(targetDir, validatedDataList, file);
            } catch (Exception e) {
                importDataFileStorageUtil.deleteDirectory(targetDir);
                throw e;
            }
        } else {
            importDataFileStorageUtil.deleteDirectory(targetDir);

        }
        IsfdDatabaseDataImportCheckVo result = new IsfdDatabaseDataImportCheckVo();
        result.setModelId(modelId);
        result.setTotalDataCount(totalDataCount);
        result.setQualifiedDataCount(qualifiedDataCount);
        result.setFailedDataCount(failedDataCount);
        result.setFailedMessage(failedMessage);
        result.setDirectoryPath(directoryPath);
        result.setFileSize(fileSize);
        return result;
    }

    public IsfdDatabaseDataValidatedDataVo checkImportDataList(Long modelId, String parentDataId, List<Map<String, Object>> dataList, Path targetDir ) {
        // 初始化返回参数
        int totalDataCount = 0;
        int qualifiedDataCount = 0;
        int failedDataCount = 0;

        List<Map<String, String>> failedMessages = new ArrayList<>();
        // 获取数据
        totalDataCount = dataList.size();
        // 匹配模型，获取字段列表
        List<IsfdDatabaseModelConfigTableVo> fieldTableList = configService.getFieldTableList(modelId);
        // 找到主模型
        IsfdDatabaseModelConfigTableVo rootTable = fieldTableList.stream()
            .filter(fieldTable -> fieldTable.getId().equals(modelId))
            .collect(Collectors.collectingAndThen(
                Collectors.toList(), list -> {
                    if (list.isEmpty()) {
                        throw new IllegalStateException("未找到主模型，请检查建模");
                    }
                    if (list.size() > 1) {
                        throw new IllegalStateException("存在多个主模型，请检查建模");
                    }
                    return list.get(0);
                }
            ));

        // 检查父模型数据是否存在
        if (StringUtils.isNotBlank(rootTable.getParentTableName())) {
            if (StringUtils.isBlank(parentDataId)) {
                throw new BaseException("未指定关联的父模型数据id");
            }
            Document parentData = mongoService.findById(rootTable.getParentTableName(), parentDataId);
            if (parentData == null) {
                throw new BaseException("未找到父模型数据！table: " + rootTable.getParentTableName() + ", id: " + parentDataId);
            }
        }

        // 检查数据
        List<Map<String, List<Map<String, Object>>>> validatedDataList = new ArrayList<>();
        for (Map<String, Object> data : dataList) {
            data.put(IsfdDatabaseModelSpecialFieldNameEnum.PARENT_ID.getValue(), parentDataId);
            try {
                validatedDataList.add(checkImportData(data, null, fieldTableList, rootTable, targetDir));
                qualifiedDataCount++;
            } catch (DataCheckFailedException dataCheckFailed) {
                ObjectMapper objectMapper = new ObjectMapper();
                String jsonString = null;
                try {
                    jsonString = objectMapper.writeValueAsString(data);
                } catch (JsonProcessingException e) {
                    throw new BaseException("数据格式有误!", e.getMessage());
                }

                String message = dataCheckFailed.getMessage();
                Map<String, String> failedData = new HashMap<>();
//                failedData.put("data", jsonString);
                failedData.put("message", message);
                failedMessages.add(failedData);
                failedDataCount++;
            }
        }

        IsfdDatabaseDataValidatedDataVo result = new IsfdDatabaseDataValidatedDataVo();
        result.setTotalDataCount(totalDataCount);
        result.setQualifiedDataCount(qualifiedDataCount);
        result.setFailedDataCount(failedDataCount);
        result.setFailedMessage(failedMessages);
        result.setValidatedData(validatedDataList);

        return result;
    }


    private Map<String, List<Map<String, Object>>> checkImportData(Map<String, Object> data, String objectIdStr, List<IsfdDatabaseModelConfigTableVo> fieldTableList, IsfdDatabaseModelConfigTableVo rootTable, Path targetDir) {
        if (CollectionUtils.isEmpty(fieldTableList)) {
            throw new IllegalStateException("模型字段列表为空");
        }
        Map<String, IsfdDatabaseModelConfigTableVo> fieldTableMap = fieldTableList.stream()
            .filter(fieldTable -> fieldTable.getFieldVoList() != null) // 过滤掉 fieldVoList 为空的项
            .collect(Collectors.toMap(
                IsfdDatabaseModelConfigTableVo::getParentFieldName,
                fieldTable -> fieldTable, // 直接存储整个对象，而不是 fieldVoList
                (existing, duplicate) -> {
                    throw new IllegalStateException("建模存在错误，重复字段名: " + existing);
                }
            ));

        List<String> errors = new ArrayList<>();
        Map<String, List<Map<String, Object>>> validatedDataMapList = new HashMap<>();
        checkImportDataRecursively(data, rootTable.getFieldVoList(), fieldTableMap, rootTable.getTableName(), null, objectIdStr, null, errors, validatedDataMapList, targetDir);
        // 如果有错误信息，统一抛出异常
        if (!errors.isEmpty()) {
            throw new DataCheckFailedException("数据校验失败: <br>" + String.join("<br>", errors));
        }
        return validatedDataMapList;
    }

    private void checkImportDataRecursively(Map<String, Object> data,
                                            List<IsfdDatabaseModelConfigFieldVo> fieldVoList,
                                            Map<String, IsfdDatabaseModelConfigTableVo> fieldTableMap,
                                            String tableName,
                                            String parentFieldName,
                                            String objectIdStr,
                                            String parentObjectIdStr,
                                            List<String> errors,
                                            Map<String, List<Map<String, Object>>> validatedDataMapList,
                                            Path targetDir) {
        if (CollectionUtils.isEmpty(fieldVoList)) {
            errors.add("字段列表为空，检查失败");
            return;
        }
        // 特殊字段提取
        data.remove(IsfdDatabaseModelSpecialFieldNameEnum.OBJECT_ID.getValue());
        String parentObjectId = (String) data.remove(IsfdDatabaseModelSpecialFieldNameEnum.PARENT_ID.getValue());
        if (StringUtils.isNotBlank(parentObjectId)) {
            parentObjectIdStr = parentObjectId;
        }

        // 多余字段检测
        Set<String> validFieldNames = fieldVoList.stream()
            .map(IsfdDatabaseModelConfigFieldVo::getFieldName)
            .collect(Collectors.toSet());

        for (String key : data.keySet()) {
            if (!validFieldNames.contains(key)) {
                errors.add("多余字段: " + key + " 在模型中未定义");
            }
        }


        Map<String, Object> validatedData = new HashMap<>();

        if (StringUtils.isBlank(parentFieldName)) {
            // 生成ObjectId
            if (StringUtils.isBlank(objectIdStr)) {
                objectIdStr = new ObjectId().toHexString();
            }
            validatedData.put(IsfdDatabaseModelSpecialFieldNameEnum.OBJECT_ID.getValue(), objectIdStr);
            // 添加父ObjectId
            if (StringUtils.isNotBlank(parentObjectIdStr)) {
                validatedData.put(IsfdDatabaseModelSpecialFieldNameEnum.PARENT_ID.getValue(), parentObjectIdStr);  // 添加父引用
            }
        }

        for (IsfdDatabaseModelConfigFieldVo fieldVo : fieldVoList) {
            String fieldName = fieldVo.getFieldName();
            Object value = data.get(fieldName);
            String fieldType = fieldVo.getFieldType();

            String currentFieldName = StringUtils.isBlank(parentFieldName) ? fieldName : parentFieldName + "." + fieldName;
            // 特殊字段不能占用
            if (IsfdDatabaseModelSpecialFieldNameEnum.allValues().contains(fieldName)) {
                throw new BaseException("特殊字段不能占用，请重命名：" + fieldName);
            }

            // 文件类型数据在页面单独导入
            if (fieldType.equals(IsfdDatabaseModelFieldTypeEnum.FILE.getValue()) ||
                fieldType.equals(IsfdDatabaseModelFieldTypeEnum.IMAGE.getValue())) {
                if (value == null) {
                    continue;
                }
                String valueString = value.toString();
                // 如果有地址
                if (StringUtils.isNotBlank(valueString)) {
                    String fileUrl = null;

                    // 判断是否是URL
                    boolean isRemoteUrl = valueString.startsWith("http://") || valueString.startsWith("https://");

                    if (isRemoteUrl) {
                        // 从完整 URL 提取 OSS Key
                        String basePrefix = iSysDictDataService.selectDictValueByTypeAndLabel(
                            CommonConstant.SYS_COMMON_DICT_TYPE,
                            CommonConstant.IMPORT_DATA_STORAGE_PREFIX
                        );
                        String ossKey = importDataFileStorageUtil.removeBaseUrl(valueString, basePrefix);
                        fileUrl = importDataFileStorageUtil.getObjectUrlIfExist(Paths.get(ossKey), basePrefix);
                    } else {
                        // 不是 URL，拼接 targetDir 获取本地路径
                        Path localFilePath = (targetDir == null) ? Paths.get(valueString) : targetDir.resolve(valueString);
                        localFilePath = localFilePath.normalize();

                        // 检查 OSS 中是否已存在
                        String basePrefix = iSysDictDataService.selectDictValueByTypeAndLabel(
                            CommonConstant.SYS_COMMON_DICT_TYPE,
                            CommonConstant.IMPORT_DATA_STORAGE_PREFIX
                        );
                        fileUrl = importDataFileStorageUtil.getObjectUrlIfExist(localFilePath, basePrefix);

                        if (StringUtils.isBlank(fileUrl)) {
                            // OSS 中也不存在，尝试本地文件是否存在
                            if (!importDataFileStorageUtil.isFileExists(localFilePath)) {
                                errors.add(fieldName + ": 地址不为空且无法找到文件，路径：" + localFilePath);
                                return;
                            }

                            // 上传到 OSS
                            try {
                                UploadResult uploadResult = importDataFileStorageUtil.uploadFileToOss(localFilePath, basePrefix);
                                if (uploadResult == null || StringUtils.isBlank(uploadResult.getUrl())) {
                                    throw new BaseException("链接为空！");
                                }
                                fileUrl = uploadResult.getUrl();
                            } catch (Exception e) {
                                errors.add(fieldName + ": 文件上传失败，路径：" + localFilePath);
                                return;
                            }

                            // 删除本地文件
                            importDataFileStorageUtil.deleteLocalFile(localFilePath);
                        }
                    }

                    data.put(fieldName, fileUrl);
                }

                continue;
            }

            // 处理为空
            if (value == null || (StringUtils.isBlank(value.toString()))) {
                // 是否允许为空
                if (fieldVo.getIsNullable() == 0 && fieldVo.getDefaultValue() == null) {
                    errors.add(fieldName + "：不能为空且没有设置默认值");
                    continue;
                }
                if (fieldVo.getDefaultValue() != null &&
                    !fieldType.equals(IsfdDatabaseModelFieldTypeEnum.MODEL.getValue()) &&
                    !fieldType.equals(IsfdDatabaseModelFieldTypeEnum.OBJECT.getValue()) &&
                    !fieldType.equals(IsfdDatabaseModelFieldTypeEnum.LIST.getValue())) {
                    value = fieldVo.getDefaultValue();
                }
            }
            if (value == null || (value instanceof String && StringUtils.isBlank((String) value))) {
                continue;
            }
            // 类型校验
            try {
                value = IsfdDatabaseModelFieldTypeEnum.convertToType(value, fieldType);
                data.put(fieldName, value);
            } catch (Exception e) {
                errors.add(fieldName + "：类型校验失败，数据类型：" + fieldType + "，数据：" + value + "，message: " + e.getMessage());
                continue;
            }
            // 嵌套数据
            if (fieldType.equals(IsfdDatabaseModelFieldTypeEnum.OBJECT.getValue())) {
                @SuppressWarnings("unchecked")
                Map<String, Object> valueMap = (Map<String, Object>) value;
                checkImportDataRecursively(valueMap, fieldVo.getFieldList(), fieldTableMap, tableName, currentFieldName,null, null, errors, validatedDataMapList, targetDir);
                validatedData.put(fieldName, valueMap);  // 保持嵌套数据在父字段中

            } else if (fieldType.equals(IsfdDatabaseModelFieldTypeEnum.LIST.getValue())) {
                @SuppressWarnings("unchecked")
                List<Map<String, Object>> valueList = (List<Map<String, Object>>) value;
                for (int i = 0; i < valueList.size(); i++) {
                    String fieldNameI = currentFieldName + "." + i;
                    Map<String, Object> valueMap = valueList.get(i);
                    checkImportDataRecursively(valueMap, fieldVo.getFieldList(), fieldTableMap, tableName, fieldNameI, null, null, errors, validatedDataMapList, targetDir);
                }

                validatedData.put(fieldName, valueList);
            } else if (fieldType.equals(IsfdDatabaseModelFieldTypeEnum.MODEL.getValue())) {
                @SuppressWarnings("unchecked")
                List<Map<String, Object>> valueList = (List<Map<String, Object>>) value;

                List<String> generatedList = new ArrayList<>();
                for (Map<String, Object> valueMap : valueList) {
                    IsfdDatabaseModelConfigTableVo childTable = fieldTableMap.get(fieldName);
                    if (childTable == null) {
                        errors.add(fieldName + "：模型字段未在建模中定义");
                        continue;
                    }

                    if (valueMap == null || valueMap.values().stream().allMatch(v -> v == null || String.valueOf(v).trim().isEmpty())) continue;

                    String childObjectIdStr ;
                    if (valueMap.containsKey(IsfdDatabaseModelSpecialFieldNameEnum.OBJECT_ID.getValue()) && StringUtils.isNotBlank((String) valueMap.get(IsfdDatabaseModelSpecialFieldNameEnum.OBJECT_ID.getValue()))) {
                        childObjectIdStr = valueMap.get(IsfdDatabaseModelSpecialFieldNameEnum.OBJECT_ID.getValue()).toString();
                    } else {
                        childObjectIdStr = new ObjectId().toHexString();
                    }



                    generatedList.add(childObjectIdStr);
                    checkImportDataRecursively(valueMap, childTable.getFieldVoList(), fieldTableMap, childTable.getTableName(), null, childObjectIdStr, objectIdStr, errors, validatedDataMapList, targetDir);
                }
                validatedData.put(fieldName, generatedList);
            } else if (fieldVo.getParentFieldId() ==null){
                validatedData.put(fieldName, value);
            }
        }

        Map<String, Object> dataWithoutId = new HashMap<>(validatedData);
        for (String specialField : IsfdDatabaseModelSpecialFieldNameEnum.allValues()) {
            dataWithoutId.remove(specialField);
        }
        // 是否包含有效数据
        boolean hasValidField = dataWithoutId.values().stream()
            .anyMatch(value -> value != null && !(value instanceof String && StringUtils.isBlank((String) value)));

        if (hasValidField && StringUtils.isBlank(parentFieldName)) {
            validatedDataMapList.computeIfAbsent(tableName, k -> new ArrayList<>()).add(validatedData);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean confirmImportData(IsfdDatabaseDataImportRecordBo recordBo) {

        // 从磁盘获取数据
        String directoryPath = recordBo.getDirectoryPath();
        Map<String, Object> cachedData = importDataFileStorageUtil.getFromDisk(directoryPath);
        List<Map<String, List<Map<String, Object>>>> validatedData =
            (List<Map<String, List<Map<String, Object>>>>) cachedData.getOrDefault("validatedData", new ArrayList<>());
        List<String> filePaths =
            (List<String>) cachedData.getOrDefault("filePaths", new ArrayList<>());
        if (CollectionUtils.isEmpty(filePaths) || CollectionUtils.isEmpty(validatedData)) {
            throw new BaseException("未找到数据！path: " + directoryPath);
        }
        recordBo.setDataFileUrl(String.join(",", filePaths));
        recordBo.setFileName(Path.of(filePaths.get(0)).getFileName().toString());

        // 保存场景/系统/模型关联关系
        Long refId = updateBusinessDatabaseRef(recordBo);
        recordBo.setBusinessDatabaseRefId(refId);

        return importDataList(recordBo, validatedData);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean importDataList(IsfdDatabaseDataImportRecordBo recordBo, List<Map<String, List<Map<String, Object>>>> validatedData) {
        // 检查是否有算法
        Long algorithmConfigId = recordBo.getAlgorithmConfigId();
        IsfdAlgorithmConfigVo isfdAlgorithmConfigVo = null;
        if (algorithmConfigId != null) {
            isfdAlgorithmConfigVo = isfdAlgorithmConfigService.queryById(algorithmConfigId);
            if(isfdAlgorithmConfigVo == null){
                throw new BaseException("未查到适用的算法，请确认后重试！");
            }
        }

        // 找到导入的主表
        IsfdDatabaseModelConfig config = baseMapper.selectById(recordBo.getModelId());
        if (config == null) {
            throw new BaseException("没有找到模型");
        }
        String mainTableName = config.getTableName();

        // 转换数据
        Map<String, List<Map<String, Object>>> transformedData = transformValidatedDataStructure(validatedData);

        // 统计数据量
        Map<String, Integer> tableDataSizeMap =  transformedData.entrySet().stream()
            .filter(entry -> entry.getValue() != null && !entry.getValue().isEmpty()) // 过滤掉 null 和空 list
            .collect(Collectors.toMap(
                Map.Entry::getKey,
                entry -> entry.getValue().size()
            ));

        // 生成导入记录
        IsfdImportMethodEnum importMethod = null;
        if (StringUtils.isBlank(recordBo.getImportMethod())) {
            importMethod = IsfdImportMethodEnum.JSON;
        } else {
            importMethod = IsfdImportMethodEnum.fromValue(recordBo.getImportMethod());
            if (importMethod == null) {
                importMethod = IsfdImportMethodEnum.JSON;
            }
        }
        IsfdDatabaseDataImportRecordBo importRecordBo = importRecordService.createImportRecord(recordBo, importMethod, mainTableName, tableDataSizeMap,  LoginHelper.getLoginUser());
        // 将导入记录记入数据，并重构数据
        IsfdDatabaseDataMongoImportRecordBo mongoImportRecord = IsfdDatabaseDataMongoImportRecordBo.createMongoImportRecord(importRecordBo);
        List<IsfdDatabaseDataAttachImportResult> dataChangeResult = attachImportRecords(transformedData, null, mongoImportRecord);

        Map<String, List<Map<String, Object>>> finalData = new HashMap<>();
        for (IsfdDatabaseDataAttachImportResult data : dataChangeResult) {
            finalData.put(data.getTableName(), data.getData()); // 这里提取每个表对应的数据列表
        }
        // 导入数据
        importData(finalData, mongoImportRecord, isfdAlgorithmConfigVo, config.getId());
        return true;
    }

    private Map<String, List<Map<String, Object>>> transformValidatedDataStructure(List<Map<String, List<Map<String, Object>>>> validatedData) {
        Map<String, List<Map<String, Object>>> transformedData = new HashMap<>();
        for (Map<String, List<Map<String, Object>>> dataMap : validatedData) {
            for (Map.Entry<String, List<Map<String, Object>>> entry : dataMap.entrySet()) {
                String tableName = entry.getKey();
                List<Map<String, Object>> dataList = new ArrayList<>(entry.getValue()); // 复制数据，防止修改原始数据
                for (Map<String, Object> data : dataList) {
                    // 将数据加入新的结构
                    transformedData.computeIfAbsent(tableName, k -> new ArrayList<>()).add(data);
                }
            }
        }
        return transformedData;
    }

    public List<IsfdDatabaseDataAttachImportResult> attachImportRecords(Map<String, List<Map<String, Object>>> validatedData,
                                                                               Map<String, List<Map<String, Object>>> existingData,
                                                                               IsfdDatabaseDataMongoImportRecordBo importRecord) {

        List<IsfdDatabaseDataAttachImportResult> dataChangeResult = new ArrayList<>();
        Set<String> processedTableNames = new HashSet<>();

        if (existingData == null) {
            existingData = Collections.emptyMap();
        }

        for (Map.Entry<String, List<Map<String, Object>>> entry : validatedData.entrySet()) {
            String tableName = entry.getKey();
            List<Map<String, Object>> newList = new ArrayList<>(entry.getValue()); // 复制数据，防止修改原始数据
            List<Map<String, Object>> oldList = existingData.getOrDefault(tableName, Collections.emptyList());
            // 使用 attachImportRecords 处理新旧数据差异
            IsfdDatabaseDataAttachImportResult attachImportResult =  attachImportRecords(newList, oldList, importRecord);
            attachImportResult.setTableName(tableName);
            dataChangeResult.add(attachImportResult);
            processedTableNames.add(tableName);
        }

        // 还要处理 validatedData 中不存在、但 oldData 中存在的表（可能是已删除）
        for (Map.Entry<String, List<Map<String, Object>>> entry : existingData.entrySet()) {
            String tableName = entry.getKey();
            if (processedTableNames.contains(tableName)) {
                continue; // 已处理
            }
            // validatedData 中不存在，说明数据被删除了
            IsfdDatabaseDataAttachImportResult attachImportResult =  attachImportRecords(Collections.emptyList(), entry.getValue(), importRecord);;
            attachImportResult.setTableName(tableName);
            dataChangeResult.add(attachImportResult);
        }

        return dataChangeResult;
    }

    public IsfdDatabaseDataAttachImportResult attachImportRecords(List<Map<String, Object>> newList, List<Map<String, Object>> oldList,
                                                                  IsfdDatabaseDataMongoImportRecordBo currentRecord) {

        // 构建旧数据 Map
        Map<String, Map<String, Object>> oldMap = oldList == null ? new HashMap<>() :
            oldList.stream()
                .peek(doc -> {
                    if (doc.get("_id") == null) {
                        throw new BaseException("旧数据中缺少 _id 字段！");
                    }
                })
                .collect(Collectors.toMap(
                    doc -> doc.get("_id").toString(),
                    Function.identity(),
                    (a, b) -> {
                        log.error("数据中存在重复 _id：" + a.get("_id"));
                        throw new BaseException("数据中存在重复 _id：" + a.get("_id"));
                    }
                ));

        // 构建新数据 Map
        Map<String, Map<String, Object>> newMap = newList == null ? new HashMap<>() :
            newList.stream()
                .peek(doc -> {
                    if (doc.get("_id") == null) {
                        log.error("新数据中缺少 _id 字段！");
                        throw new BaseException("新数据中缺少 _id 字段！");
                    }
                })
                .collect(Collectors.toMap(
                    doc -> doc.get("_id").toString(),
                    Function.identity(),
                    (a, b) -> {
                        log.error("数据中存在重复 _id：" + a.get("_id"));
                        throw new BaseException("数据中存在重复 _id：" + a.get("_id"));
                    }
                ));

        List<Map<String, Object>> result = new ArrayList<>();
        int createdCount = 0;
        int deletedCount = 0;

        // 处理 updated / created
        for (Map.Entry<String, Map<String, Object>> entry : newMap.entrySet()) {
            String id = entry.getKey();
            Map<String, Object> newDoc = entry.getValue();
            IsfdDatabaseDataMongoImportRecordBo importRecord = oldMap.containsKey(id)
                ? IsfdDatabaseDataMongoImportRecordBo.updateMongoImportRecord(currentRecord)
                : IsfdDatabaseDataMongoImportRecordBo.createMongoImportRecord(currentRecord);
            newDoc.put(IsfdDatabaseModelSpecialFieldNameEnum.IMPORT_METHOD.getValue(), importRecord.toMap());
            result.add(newDoc);
            if (!oldMap.containsKey(id)) {
                createdCount++;
            }
        }

        // 处理 deleted
        for (Map.Entry<String, Map<String, Object>> entry : oldMap.entrySet()) {
            String id = entry.getKey();
            if (!newMap.containsKey(id)) {
                Map<String, Object> deletedDoc = entry.getValue();
                IsfdDatabaseDataMongoImportRecordBo importRecord = IsfdDatabaseDataMongoImportRecordBo.updateMongoImportRecordDeleteFlag(currentRecord, 1);
                deletedDoc.put(IsfdDatabaseModelSpecialFieldNameEnum.IMPORT_METHOD.getValue(), importRecord.toMap());
                result.add(deletedDoc);
                deletedCount++;
            }
        }

        IsfdDatabaseDataAttachImportResult attachImportResult = new IsfdDatabaseDataAttachImportResult();
        attachImportResult.setData(result);
        attachImportResult.setCreatedCount(createdCount);
        attachImportResult.setDeletedCount(deletedCount);
        attachImportResult.setExistedCount(oldMap.size());


        return attachImportResult;
    }

    @Transactional(rollbackFor = Exception.class)
    public void importData(Map<String, List<Map<String, Object>>> finalData,
                               IsfdDatabaseDataMongoImportRecordBo importRecord,
                               IsfdAlgorithmConfigVo isfdAlgorithmConfigVo,
                               Long modelId) {

        // 考虑导入子模型的情况
        IsfdDatabaseModelConfig rootConfig = baseMapper.selectById(modelId);
        String rootTableName = rootConfig.getTableName();
        Document originalParentData = new Document();
        String parentTableName = null;
        String parentId = null;
        if (rootConfig.getParentConfigId() != null) {
            IsfdDatabaseModelConfig parentConfig = baseMapper.selectById(rootConfig.getParentConfigId());
            parentTableName = parentConfig.getTableName();
            List<Map<String, Object>> rootTableData = finalData.get(rootTableName);
            if (rootTableData == null || rootTableData.isEmpty()) {
                throw new IllegalStateException("主表数据为空: " + rootTableName);
            }
            Set<String> distinctParentIds = rootTableData.stream()
                .map(row -> row.get(IsfdDatabaseModelSpecialFieldNameEnum.PARENT_ID.getValue()))
                .filter(Objects::nonNull)
                .map(Object::toString)
                .collect(Collectors.toSet());
            if (distinctParentIds.isEmpty()) {
                throw new IllegalStateException("主表数据缺少parentId: " + rootTableName);
            }
            if (distinctParentIds.size() > 1) {
                throw new IllegalStateException("主表数据parentId不一致" + distinctParentIds);
            }
            parentId = distinctParentIds.iterator().next();
            List<String> objectIds = rootTableData.stream()
                .map(data -> data.get(IsfdDatabaseModelSpecialFieldNameEnum.OBJECT_ID.getValue()))
                .filter(Objects::nonNull)
                .map(Object::toString)
                .collect(Collectors.toList());
            originalParentData = updateParentData(parentTableName, rootConfig.getParentConfigFieldName(), parentId, objectIds);
        }

        // 更新模型
        List<String> tableNames = finalData.keySet().stream().toList();
        List<IsfdDatabaseModelConfig> modelConfigs = baseMapper.selectList(
            new LambdaQueryWrapper<>(IsfdDatabaseModelConfig.class)
                .in(IsfdDatabaseModelConfig::getTableName, tableNames)
        );
        for (IsfdDatabaseModelConfig modelConfig : modelConfigs) {
            modelConfig.setIsPublished(1);
        }
        baseMapper.updateBatchById(modelConfigs);

        // 导入数据
        try {
            if (isfdAlgorithmConfigVo != null) {
                saveDataToMongo(finalData, isfdAlgorithmConfigVo);
            } else {
                saveDataToMongo(finalData);
            }
        } catch (Exception e) {
            String message = String.format("数据导入失败, message: " + e.getMessage());
            log.error("数据导入失败", e);
            // 要回滚当前已经写入的数据
            Map<String, Object> deleteData = new HashMap<>();
            deleteData.put("importRecord.id", importRecord.getId());
            for (String collectionName : finalData.keySet()) {
                mongoService.delete(collectionName , deleteData);
            }
            if (rootConfig.getParentConfigId() != null) {
                mongoService.updateById(parentTableName, parentId, originalParentData);
            }
            throw new BaseException(message);
        }
    }

    @Transactional(rollbackFor = Exception.class)
    public Long updateBusinessDatabaseRef(IsfdDatabaseDataImportRecordBo recordBo) {
        IsfdBusinessDatabaseRefBo refBo = new IsfdBusinessDatabaseRefBo();
        refBo.setDatabaseTypeId(recordBo.getDatabaseTypeId());
        refBo.setSceneId(recordBo.getSceneId());
        refBo.setSystemId(recordBo.getSystemId());
        IsfdDatabaseModelConfig topParent = configService.queryByIdReturnTopParent(recordBo.getModelId());
        refBo.setParentModelId(topParent.getId());
        businessDatabaseRefService.updateHaveImportData(refBo);
        return refBo.getId();
    }

    @Transactional(rollbackFor = Exception.class)
    public  void saveDataToMongo(Map<String, List<Map<String, Object>>> data) {
        for (Map.Entry<String, List<Map<String, Object>>> entry : data.entrySet()) {
            String tableName = entry.getKey();
            List<Map<String, Object>> dataList = entry.getValue();
            List<String> dataIds = mongoService.saveBatch(tableName, dataList);
            if (CollectionUtils.isEmpty(dataIds)) {
                throw new BaseException("id列表为空！");
            }
        }
    }

    @Transactional(rollbackFor = Exception.class)
    public void saveDataToMongo(Map<String, List<Map<String, Object>>> data, IsfdAlgorithmConfigVo isfdAlgorithmConfigVo) {
        for (Map.Entry<String, List<Map<String, Object>>> entry : data.entrySet()) {
            String tableName = entry.getKey();
            List<Map<String, Object>> dataList = entry.getValue();
            // 加入算法计算
            isfdAlgorithmConfigService.calculate(dataList, isfdAlgorithmConfigVo.getId());
            List<String> dataIds = mongoService.saveBatch(tableName, dataList);
            if (CollectionUtils.isEmpty(dataIds)) {
                throw new BaseException("id列表为空！");
            }
        }
    }

    public List<Document> queryDataOfOneTableWithLogicDelete(String tableName, IsfdDatabaseMongoQuery queryCondition) {
        // 复制 queryCondition（浅拷贝）
        IsfdDatabaseMongoQuery newQuery = new IsfdDatabaseMongoQuery();
        newQuery.setPageQuery(queryCondition.getPageQuery());

        List<IsfdDatabaseMongoQuery.IsfdDatabaseMongoQueryCondition> conditions = new ArrayList<>();
        if (!CollectionUtils.isEmpty(queryCondition.getConditions())) {
            conditions.addAll(queryCondition.getConditions()); // 共享旧的条件，不修改原列表
        }

        // 添加逻辑删除条件
        IsfdDatabaseMongoQuery.IsfdDatabaseMongoQueryCondition deleteCondition = new IsfdDatabaseMongoQuery.IsfdDatabaseMongoQueryCondition();
        deleteCondition.setFieldName(IsfdDatabaseModelSpecialFieldNameEnum.IMPORT_METHOD.getValue() + ".delete_flag");
        deleteCondition.setOperator("eq");
        deleteCondition.setValue("0");
        deleteCondition.setValueNumberCheck(true);
        deleteCondition.setLogicalOperator("and");

        conditions.add(deleteCondition);
        newQuery.setConditions(conditions);

        return (newQuery.getPageQuery() != null)
            ? mongoService.aggregationQuery(tableName, newQuery)
            : mongoService.findAll(tableName, newQuery);
    }

    public Long queryDataCountOneTableWithLogicDelete(String tableName, IsfdDatabaseMongoQuery queryCondition) {
        // 复制 queryCondition（浅拷贝）
        IsfdDatabaseMongoQuery newQuery = new IsfdDatabaseMongoQuery();
        newQuery.setPageQuery(queryCondition.getPageQuery());

        List<IsfdDatabaseMongoQuery.IsfdDatabaseMongoQueryCondition> conditions = new ArrayList<>();
        if (!CollectionUtils.isEmpty(queryCondition.getConditions())) {
            conditions.addAll(queryCondition.getConditions()); // 共享旧的条件，不修改原列表
        }

        // 添加逻辑删除条件
        IsfdDatabaseMongoQuery.IsfdDatabaseMongoQueryCondition deleteCondition = new IsfdDatabaseMongoQuery.IsfdDatabaseMongoQueryCondition();
        deleteCondition.setFieldName(IsfdDatabaseModelSpecialFieldNameEnum.IMPORT_METHOD.getValue() + ".delete_flag");
        deleteCondition.setOperator("eq");
        deleteCondition.setValue("0");
        deleteCondition.setValueNumberCheck(true);
        deleteCondition.setLogicalOperator("and");

        conditions.add(deleteCondition);
        newQuery.setConditions(conditions);

        return mongoService.count(tableName, newQuery);
    }


    @Override
    public List<Object> queryDataDetail(String tableName, String objectId, IsfdDatabaseMongoQuery queryCondition) {
        IsfdDatabaseModelConfig mainModel = baseMapper.selectOne(new LambdaQueryWrapper<IsfdDatabaseModelConfig>()
            .eq(IsfdDatabaseModelConfig::getTableName, tableName));
        if (mainModel == null) {
            throw new BaseException("没有找到关联模型");
        }

        if (CollectionUtils.isEmpty(queryCondition.getConditions())) {
            queryCondition.setConditions(new ArrayList<>());
        }
        // 构造id筛选条件
        if (StringUtils.isNotBlank(objectId)) {
            IsfdDatabaseMongoQuery.IsfdDatabaseMongoQueryCondition idQuery = new IsfdDatabaseMongoQuery.IsfdDatabaseMongoQueryCondition();
            idQuery.setFieldName(IsfdDatabaseModelSpecialFieldNameEnum.OBJECT_ID.getValue());
            idQuery.setOperator("eq");
            idQuery.setValue(objectId);
            queryCondition.getConditions().add(idQuery);
        }

        // 获取所有Table
        List<IsfdDatabaseModelConfigTableVo> fieldTableList = configService.getFieldTableList(mainModel.getId()); // 转换为列表
        Map<String, List<Document>> dataTableMap = new LinkedHashMap<>();
        Map<String, String> childTableNameMap =  getChildTableNameMap( fieldTableList);
        Map<String, List<IsfdDatabaseModelConfigFieldVo>> fieldListMap = getFieldListMap(fieldTableList);

        // 将主模型单独拎出来
        IsfdDatabaseModelConfigTableVo mainTable = fieldTableList.remove(fieldTableList.size() - 1);

        // 是否有子表
        boolean hasChildren = fieldTableList.stream()
            .anyMatch(fieldTable ->
                fieldTable.getParentTableName().equals(mainTable.getTableName())
                    && (fieldTable.getShowType().equals(IsfdDatabaseModelShowTypeEnum.TREE.getValue())));
        // 没有子表 == 最后一层树 == 加载全部

        List<Document> mainDataList = queryDataOfOneTableWithLogicDelete(mainTable.getTableName(), queryCondition);

        dataTableMap.put(mainTable.getTableName(), mainDataList);

        // 获取完整数据列表
        if (!hasChildren) {
            for (int i = fieldTableList.size() - 1; i >= 0; i--) {
                IsfdDatabaseModelConfigTableVo fieldTable = fieldTableList.get(i);
                queryCondition.setConditions(new ArrayList<>());
                List<Document> dataList = queryDataOfOneTableWithLogicDelete(fieldTable.getTableName(), queryCondition);
                dataTableMap.put(fieldTable.getTableName(), dataList);
            }
        }

        // 递归所有数据
        List<Document> mergedData = new ArrayList<>(dataTableMap.get(mainTable.getTableName()));
        if (mergedData.isEmpty()) {
            throw new BaseException("未查询到数据！");
        }

        List<Object> result = new ArrayList<>();
        for (Document mergedOneData : mergedData) {
            // 递归模式： 0-不递归，1-完全递归， 2-只递归树模型
            List<Object> dataWithCompleteInfo =  mergeDataRecursivelyWithCompleteInfo(dataTableMap, mergedOneData, childTableNameMap, mainTable.getTableName(), fieldListMap.get(mainTable.getTableName()), fieldListMap, null, hasChildren);
            result.add(dataWithCompleteInfo);
        }
        return result;
}

    private Map<String, String> getChildTableNameMap(List<IsfdDatabaseModelConfigTableVo> fieldTableList) {
        Map<String, String> childTableNameMap = new LinkedHashMap<>();
        for (IsfdDatabaseModelConfigTableVo fieldTable : fieldTableList) {
            String tableName = fieldTable.getTableName();
            String parentTableName = fieldTable.getParentTableName();
            if (StringUtils.isBlank(parentTableName)) {
                continue;
            }
            String parentFieldName = fieldTable.getParentFieldName();
            String key = parentTableName + "." + parentFieldName;
            childTableNameMap.put(key, tableName);
        }
        return childTableNameMap;
    }

    private Map<String, List<IsfdDatabaseModelConfigFieldVo>> getFieldListMap(List<IsfdDatabaseModelConfigTableVo> fieldTableList) {
        Map<String,  List<IsfdDatabaseModelConfigFieldVo>> fieldListMap = new LinkedHashMap<>();
        for (IsfdDatabaseModelConfigTableVo fieldTable : fieldTableList) {
            String tableName = fieldTable.getTableName();
            List<IsfdDatabaseModelConfigFieldVo> fieldList = fieldTable.getFieldVoList();
            fieldListMap.put(tableName, fieldList);
        }
        return fieldListMap;
    }


    @Override
    public List<Document> queryDataAll(Long modelId, IsfdDatabaseMongoQuery queryCondition) {
        queryCondition.setPageQuery(null);
        return queryDataPaged(modelId, queryCondition);
    }

    @Override
    public List<Document> queryDataPaged(Long modelId, IsfdDatabaseMongoQuery queryCondition) {

        // 获取主模型
        IsfdDatabaseModelConfig mainModel = baseMapper.selectById(modelId);
        if (mainModel == null) {
            throw new BaseException("未找到模型！id: " + modelId);
        }
        // 获取所有表名
        List<IsfdDatabaseModelConfigTableVo> fieldTableList = configService.getFieldTableList(mainModel.getId()); // 转换为列表
        Map<String, List<Document>> dataTableMap = new LinkedHashMap<>();
        Map<String, String> childTableNameMap = getChildTableNameMap(fieldTableList);

        // 将主模型单独拎出来
        IsfdDatabaseModelConfigTableVo mainTable = fieldTableList.remove(fieldTableList.size() - 1);

        List<Document> mainDataList = queryDataOfOneTableWithLogicDelete(mainTable.getTableName(), queryCondition);

        dataTableMap.put(mainTable.getTableName(), mainDataList);


        // 获取完整数据列表
        for (int i = fieldTableList.size() - 1; i >= 0; i--) {
            IsfdDatabaseModelConfigTableVo fieldTable = fieldTableList.get(i);
            queryCondition.setConditions(new ArrayList<>());
            List<Document> dataList = queryDataOfOneTableWithLogicDelete(fieldTable.getTableName(), queryCondition);
            dataTableMap.put(fieldTable.getTableName(), dataList);
        }

        // 递归所有数据
        List<Document> mainData = new ArrayList<>(dataTableMap.get(mainTable.getTableName()));
        List<Document> mergedData = new ArrayList<>();
        for (Document doc : mainData) {
            doc = mergeDataRecursivelyAsJson(dataTableMap, doc, childTableNameMap,mainTable.getTableName());
            mergedData.add(doc);
        }
        return mergedData;
    }

    /**
     * 拼接一条完整数据
     */
    private Document mergeDataRecursivelyAsJson(Map<String, List<Document>> dataTableMap, Document mergedOneData, Map<String, String> childTableNameMap,
                                                String currentTableName) {

        Document document = mergedOneData;

        List<String> keysToRemove = new ArrayList<>();

        for (String key : document.keySet()) {
            String currentFieldName = currentTableName + "." + key;
            Object value = document.get(key);

            if (value == null) continue;

            if (key.equals(IsfdDatabaseModelSpecialFieldNameEnum.OBJECT_ID.getValue())|| key.equals(IsfdDatabaseModelSpecialFieldNameEnum.PARENT_ID.getValue())) {
//                keysToRemove.add(key);
                continue;
            }

            if (key.equals(IsfdDatabaseModelSpecialFieldNameEnum.IMPORT_METHOD.getValue())) {
                keysToRemove.add(key);
                continue;
            }

            // 检查字段是否是普通数据
            if (!(value instanceof List<?>)) {
                continue;
            }

            // 判断是不是模型
            if (!childTableNameMap.containsKey(currentFieldName)) {
                continue;
            }

            // 是模型
            @SuppressWarnings("unchecked")
            List<String> list = (List<String>) value;

            List<Object> relatedDataList = new ArrayList<>();

            for (String item : list) {
                String tableName = childTableNameMap.get(currentFieldName);
                String objectId = item;

                // 查找对应表数据
                List<Document> relatedData = dataTableMap.get(tableName);
                if (relatedData == null) {
                    continue;
                }

                // 查找对应 objectId 的数据
                for (Document relatedDocument : relatedData) {
                    if (objectId.equals(relatedDocument.get(IsfdDatabaseModelSpecialFieldNameEnum.OBJECT_ID.getValue()))) {
                        // 递归处理子表数据
                        Document wrappedSubDoc = mergeDataRecursivelyAsJson(dataTableMap, relatedDocument, childTableNameMap, tableName);
                        relatedDataList.add(wrappedSubDoc);
                        break;
                    }
                }
            }
            document.put(key, relatedDataList);
        }

        for (String key : keysToRemove) {
            document.remove(key);
        }

        document.entrySet().removeIf(entry -> entry.getValue() == null);

        return document;
    }


    public List<Document> queryDataByModelHasRecord(Long modelId, IsfdDatabaseMongoQuery queryCondition) {

        // 增加逻辑删除筛选
        IsfdDatabaseMongoQuery.IsfdDatabaseMongoQueryCondition logicalDeleteQuery = new IsfdDatabaseMongoQuery.IsfdDatabaseMongoQueryCondition();
        logicalDeleteQuery.setFieldName(IsfdDatabaseModelSpecialFieldNameEnum.IMPORT_METHOD.getValue() + "." + "delete_flag");
        logicalDeleteQuery.setOperator("eq");
        logicalDeleteQuery.setValue("0");
        logicalDeleteQuery.setValueNumberCheck(true);
        // 查询数据
        if (CollectionUtils.isEmpty(queryCondition.getConditions())) {
            queryCondition.setConditions(new ArrayList<>());
        }
        queryCondition.getConditions().add(logicalDeleteQuery);

        // 获取所有Table
        List<IsfdDatabaseModelConfigTableVo> fieldTableList = configService.getFieldTableList(modelId); // 转换为列表
        Map<String, List<Document>> dataTableMap = new LinkedHashMap<>();
        Map<String, String> showTypeMap = new LinkedHashMap<>();

        // 将主模型单独拎出来

        IsfdDatabaseModelConfigTableVo mainTable = fieldTableList.remove(fieldTableList.size() - 1);

        List<Document> mainDataList = mongoService.aggregationQueryHasRecord(mainTable.getTableName(), queryCondition);

        dataTableMap.put(mainTable.getTableName(), mainDataList);
        showTypeMap.put(mainTable.getTableName(), mainTable.getShowType()); // 展示方式

        // 获取完整数据列表
        for (int i = fieldTableList.size() - 1; i >= 0; i--) {
            IsfdDatabaseModelConfigTableVo fieldTable = fieldTableList.get(i);
            List<Document> dataList = queryDataOfOneTableWithLogicDelete(fieldTable.getTableName(), queryCondition);
            dataTableMap.put(fieldTable.getTableName(), dataList);
            showTypeMap.put(fieldTable.getTableName(), fieldTable.getShowType());

        }

        // 递归所有数据
        List<Document> mergedData = new ArrayList<>(dataTableMap.get(mainTable.getTableName()));

        Integer mergeMode = 0;
//        return mergeDataRecursively(dataTableMap, mergedData, showTypeMap, mergeMode, fieldChineseMap, mainTable.getTableName());
        return mergedData;
    }

    private List<Object> mergeDataRecursivelyWithCompleteInfo(Map<String, List<Document>> dataTableMap, Document mergedOneData, Map<String, String> childTableNameMap,
                                                              String currentTableName,
                                                              List<IsfdDatabaseModelConfigFieldVo> currentFieldList,
                                                              Map<String, List<IsfdDatabaseModelConfigFieldVo>> fiedlListMap,
                                                              String currentObjectId,
                                                              boolean hasChildren) {

        Document document = mergedOneData;

        // 处理特殊字段
        Object parentId = document.get(IsfdDatabaseModelSpecialFieldNameEnum.PARENT_ID.getValue());
        Object id = document.get(IsfdDatabaseModelSpecialFieldNameEnum.OBJECT_ID.getValue());
        if (id != null) {
            currentObjectId = id.toString();
            Document idInfo = completeDataInfo(IsfdDatabaseModelSpecialFieldNameEnum.OBJECT_ID.getValue(), id, "ID", "info", currentTableName, currentObjectId);
            document.put(IsfdDatabaseModelSpecialFieldNameEnum.OBJECT_ID.getValue(), idInfo);
        }
        if (parentId != null) {
            Document parentInfo = completeDataInfo(IsfdDatabaseModelSpecialFieldNameEnum.PARENT_ID.getValue(), parentId, "父ID", "info", currentTableName, currentObjectId);
            document.put(IsfdDatabaseModelSpecialFieldNameEnum.PARENT_ID.getValue(), parentInfo);
        }
        document.remove(IsfdDatabaseModelSpecialFieldNameEnum.IMPORT_METHOD.getValue());

        for (IsfdDatabaseModelConfigFieldVo currentField : currentFieldList) {

            // 字段名称
            String key = currentField.getFieldName();

            // 字段中文名
            String chinese = currentField.getFieldChineseName();

            // 字段类型
            String fieldType = currentField.getFieldType();

            // 索引
            String currentTableFieldName = currentTableName + "." + key;
            // 数据
            Object value = document.get(key);
            if (value == null) {
                document.put(key, "");
                value = "";
            }

            // 检查字段是否是普通数据
            if (!fieldType.equals(IsfdDatabaseModelFieldTypeEnum.OBJECT.getValue()) &&
                !fieldType.equals(IsfdDatabaseModelFieldTypeEnum.MODEL.getValue()) &&
                !fieldType.equals(IsfdDatabaseModelFieldTypeEnum.LIST.getValue())) {

                String fieldShowType = "basic";
                if (fieldType.equals(IsfdDatabaseModelFieldTypeEnum.IMAGE.getValue())) {
                    fieldShowType = "image";
                } else if (fieldType.equals(IsfdDatabaseModelFieldTypeEnum.FILE.getValue())) {
                    fieldShowType = "file";
                }

                Document completeData = completeDataInfo(key, value, chinese, fieldShowType, currentTableName, currentObjectId);
                document.put(key, completeData);
                continue;
            }

            // 判断是不是对象
            if (fieldType.equals(IsfdDatabaseModelFieldTypeEnum.OBJECT.getValue())) {

                Document objectDocument;

                if (value instanceof Map) {
                    @SuppressWarnings("unchecked")
                    Map<String, Object> mapValue = (Map<String, Object>) value;
                    objectDocument = new Document(mapValue);
                } else {
                    // 如果值为 null、空字符串或其他非 Map 类型，初始化一个空 Document
                    objectDocument = new Document();
                }

                List<Object> wrappedSubList = mergeDataRecursivelyWithCompleteInfo(dataTableMap, objectDocument, childTableNameMap, currentTableName, currentField.getFieldList(), fiedlListMap, currentObjectId, hasChildren);
                Document completeData = completeDataInfo(key, wrappedSubList, chinese, "object", currentTableName, currentObjectId);
                document.put(key, completeData);
                continue;
            }

            // 是列表
            if (fieldType.equals(IsfdDatabaseModelFieldTypeEnum.LIST.getValue())) {
                List<Map<String, Object>> list;
                if (value instanceof List<?> rawList) {
                    list = rawList.stream()
                        .filter(item -> item instanceof Map)
                        .map(item -> (Map<String, Object>) item)
                        .collect(Collectors.toList()); // 可变列表
                } else if (StringUtils.isBlank((String) value)) {
                    list = new ArrayList<>(); // 空字符串视为空列表
                } else {
                    throw new IllegalArgumentException("字段 value 不是 List<Map> 类型，也不是空字符串或 null");
                }

                List<Object> objectDataList = new ArrayList<>();

                for (int i = 0; i < list.size(); i++) {
                    Map<String, Object> objectData = list.get(i);
                    Document objectDocument = new Document(objectData);
                    List<Object> wrappedSubList = mergeDataRecursivelyWithCompleteInfo(dataTableMap, objectDocument, childTableNameMap, currentTableName, currentField.getFieldList(), fiedlListMap, currentObjectId, hasChildren);
                    objectDataList.add(wrappedSubList);
                }

                Document completeData = completeDataInfo(key, objectDataList, chinese, "table", currentTableName, currentObjectId);
                document.put(key, completeData);
                continue;
            }

            // 是模型

            if (hasChildren) {
                document.remove(key);
                continue;
            }

            List<String> list;
            if (value instanceof List<?> rawList) {
                list = rawList.stream()
                    .filter(item -> item instanceof String)
                    .map(item -> (String) item)
                    .toList();
            } else if (StringUtils.isBlank((String) value)) {
                // 空字符串视为空列表
                list = new ArrayList<>();
            } else {
                throw new IllegalArgumentException("字段 value 不是 List<String> 类型，也不是空字符串或 null");
            }

            List<Object> relatedDataList = new ArrayList<>();
            String tableName = childTableNameMap.get(currentTableFieldName);
            if (tableName == null) {
                continue;
            }
            List<Document> relatedData = dataTableMap.getOrDefault(tableName, new ArrayList<>());

            // 正常处理每个 objectId
            for (String objectId : list) {
                for (Document relatedDocument : relatedData) {
                    if (objectId.equals(relatedDocument.get(IsfdDatabaseModelSpecialFieldNameEnum.OBJECT_ID.getValue()))) {
                        List<Object> wrappedSubList = mergeDataRecursivelyWithCompleteInfo(
                            dataTableMap, relatedDocument,
                            childTableNameMap, tableName, fiedlListMap.get(tableName), fiedlListMap,
                            objectId,
                            hasChildren);
                        relatedDataList.add(wrappedSubList);
                        break;
                    }
                }
            }

            // 如果为空，仍然递归一次补充示例数据
            if (relatedDataList.isEmpty() && !hasChildren) {
                List<Object> wrappedSubList = mergeDataRecursivelyWithCompleteInfo(
                    dataTableMap, new Document(),
                    childTableNameMap, tableName, fiedlListMap.get(tableName), fiedlListMap,
                    null,
                    hasChildren);
                relatedDataList.add(wrappedSubList);
            }

            Document completeData = completeDataInfo(key, relatedDataList, chinese, "table", currentTableName, currentObjectId);
            document.put(key, completeData);
        }

        // 只保留 currentFieldList 中定义过的字段 + 特殊字段（如 OBJECT_ID、PARENT_ID）
        Set<String> allowedKeys = currentFieldList.stream()
            .map(IsfdDatabaseModelConfigFieldVo::getFieldName)
            .collect(Collectors.toSet());
        allowedKeys.add(IsfdDatabaseModelSpecialFieldNameEnum.OBJECT_ID.getValue());
        allowedKeys.add(IsfdDatabaseModelSpecialFieldNameEnum.PARENT_ID.getValue());

        document.keySet().removeIf(key -> !allowedKeys.contains(key));

        // 按照 id 排序 currentFieldList
        List<String> fieldOrder = new ArrayList<>(currentFieldList.stream()
            .sorted(Comparator.comparing(IsfdDatabaseModelConfigFieldVo::getId))
            .map(IsfdDatabaseModelConfigFieldVo::getFieldName)
            .toList());
        // 添加特殊字段顺序（放在最后或你想要的位置）
        fieldOrder.add(IsfdDatabaseModelSpecialFieldNameEnum.OBJECT_ID.getValue());
        fieldOrder.add(IsfdDatabaseModelSpecialFieldNameEnum.PARENT_ID.getValue());

        // 根据排序后的 fieldOrder 从 document 中取值，并去除 null

        return fieldOrder.stream()
            .filter(document::containsKey)
            .map(document::get)
            .filter(Objects::nonNull)
            .toList();
    }

    @Override
    public IsfdDatabaseDataPageResultVo queryDataShowAsTableOrTree(IsfdDatabaseDataTreeQueryBo queryCondition) {
        // 以模型id为主. 找到主模型
        Long modelId = queryCondition.getModelId();
        String tableName = queryCondition.getTableName();
        IsfdDatabaseModelConfig mainModel = null;
        if (modelId != null) {
            mainModel = baseMapper.selectById(modelId);
        } else if (tableName != null) {
            mainModel = baseMapper.selectOne(new LambdaQueryWrapper<IsfdDatabaseModelConfig>()
                .eq(IsfdDatabaseModelConfig::getTableName, tableName));
        }
        ;
        if (mainModel == null) {
            throw new BaseException("没有找到关联模型");
        }

        IsfdDatabaseDataPageResultVo pageResultVo = new IsfdDatabaseDataPageResultVo();
        pageResultVo.setShowType(mainModel.getShowType());

        if (mainModel.getShowType().equals(IsfdDatabaseModelShowTypeEnum.TABLE.getValue())) {
            if (queryCondition.getPageNum() == null || queryCondition.getPageSize() == null) {
                throw new BaseException("分页条件不能为空！");
            }
            pageResultVo.setTableResult(queryDataTable(queryCondition));
        } else if (mainModel.getShowType().equals(IsfdDatabaseModelShowTypeEnum.TREE.getValue())){
            pageResultVo.setTreeResult(queryDataTree(queryCondition));
        } else {
            throw new BaseException("不支持的展示类型： " + mainModel.getShowType());
        }
        return pageResultVo;
    }

    @Override
    public IsfdDatabaseDataTreeResultVo queryDataTree(IsfdDatabaseDataTreeQueryBo queryCondition) {
        // 以模型id为主. 找到主模型
        Long modelId = queryCondition.getModelId();
        String tableName = queryCondition.getTableName();
        IsfdDatabaseModelConfig mainModel = null;
        if (modelId != null) {
            mainModel = baseMapper.selectById(modelId);
        } else if (StringUtils.isNotBlank(tableName)) {
            mainModel = baseMapper.selectOne(new LambdaQueryWrapper<IsfdDatabaseModelConfig>()
                .eq(IsfdDatabaseModelConfig::getTableName, tableName));
        }

        if (mainModel == null) {
            throw new BaseException("没有找到关联模型");
        }

        // 获取所有Table
        List<IsfdDatabaseModelConfigTableVo> fieldTableList = configService.getFieldTableList(mainModel.getId()); // 转换为列表
        Map<String, List<Document>> dataTableMap = new LinkedHashMap<>();
        Map<String, Map<String, List<String>>> treeDisplayFieldMap = getTreeDisplayFieldMap(fieldTableList);
        Map<String, String> childTableNameMap = getChildTableNameMap(fieldTableList);

        // 将主模型单独拎出来
        IsfdDatabaseModelConfigTableVo mainTable = fieldTableList.remove(fieldTableList.size() - 1);

        // 检验父节点信息
//        String parentTable = mainTable.getParentTableName();
//        if (StringUtils.isNotBlank(parentTable)) {
//            String parentId = queryCondition.getParentId();
//            if (StringUtils.isBlank(parentId)) {
//                log.error("当前节点存在父表，但parentId为空！ tableName: " + tableName);
//                throw new BaseException("当前节点存在父表，但parentId为空！ tableName: " + tableName);
//            }
//        }

        // 拼接查询条件
        IsfdDatabaseMongoQuery mongoQuery = new IsfdDatabaseMongoQuery();
        mongoQuery.setConditions(new ArrayList<>());

        // 分页
        PageQuery pageQuery = new PageQuery();
        pageQuery.setPageSize(queryCondition.getPageSize());
        pageQuery.setPageNum(queryCondition.getPageNum());
        mongoQuery.setPageQuery(pageQuery);

        // 模糊查询
        String keyword = queryCondition.getKeyword();
        if (StringUtils.isNotBlank(keyword)) {
            // 字段列表
            List<IsfdDatabaseModelConfigFieldVo> fieldVoList = mainTable.getFieldVoList();
            List<String> searchFieldList = buildSearchFieldList(fieldVoList);

            // 构造关键词模糊查询条件（$or）
            List<IsfdDatabaseMongoQuery.IsfdDatabaseMongoQueryCondition> fuzzyConditions = new ArrayList<>();
            for (String field : searchFieldList) {
                IsfdDatabaseMongoQuery.IsfdDatabaseMongoQueryCondition condition = new IsfdDatabaseMongoQuery.IsfdDatabaseMongoQueryCondition();
                condition.setFieldName(field);
                condition.setOperator(IsfdMongoQueryOperatorEnum.LIKE.getValue()); // 你定义的 LIKE 映射到 $regex
                condition.setValue(keyword);
                condition.setLogicalOperator(IsfdMongoQueryLogicalOperatorEnum.OR.getValue());
                fuzzyConditions.add(condition);
            }
            mongoQuery.getConditions().addAll(fuzzyConditions);
        }

        // 父id
        String parentId = queryCondition.getParentId();
        if (StringUtils.isNotBlank(parentId)) {
            IsfdDatabaseMongoQuery.IsfdDatabaseMongoQueryCondition parentIdQueryCondition = new IsfdDatabaseMongoQuery.IsfdDatabaseMongoQueryCondition();
            parentIdQueryCondition.setFieldName(IsfdDatabaseModelSpecialFieldNameEnum.PARENT_ID.getValue());
            parentIdQueryCondition.setOperator(IsfdMongoQueryOperatorEnum.EQUAL.getValue());
            parentIdQueryCondition.setValue(parentId);
            mongoQuery.getConditions().add(parentIdQueryCondition);
        }

        // _id
        List<String> objectIds = queryCondition.getObjectIds();
        boolean hasValidId = objectIds != null && objectIds.stream()
            .anyMatch(StringUtils::isNotBlank);
        if (hasValidId) {
            IsfdDatabaseMongoQuery.IsfdDatabaseMongoQueryCondition objIdsQueryCondition = new IsfdDatabaseMongoQuery.IsfdDatabaseMongoQueryCondition();
            objIdsQueryCondition.setFieldName(IsfdDatabaseModelSpecialFieldNameEnum.OBJECT_ID.getValue());
            objIdsQueryCondition.setOperator(IsfdMongoQueryOperatorEnum.INCLUDES.getValue());
            objIdsQueryCondition.setValue(String.join(",", objectIds));
            objIdsQueryCondition.setLogicalOperator(IsfdMongoQueryLogicalOperatorEnum.AND.getValue());
            mongoQuery.getConditions().add(objIdsQueryCondition);
        }

        // 导入记录
        List<Long> rawIds = queryCondition.getImportRecordIds();
        List<Long> recordIds = Optional.ofNullable(rawIds)
            .orElse(Collections.emptyList())
            .stream()
            .filter(Objects::nonNull)
            .toList();
        if (!CollectionUtils.isEmpty(recordIds)) {
            IsfdDatabaseMongoQuery.IsfdDatabaseMongoQueryCondition recordIdsQueryCondition = new IsfdDatabaseMongoQuery.IsfdDatabaseMongoQueryCondition();
            recordIdsQueryCondition.setFieldName(IsfdDatabaseModelSpecialFieldNameEnum.IMPORT_METHOD.getValue() + ".id");
            recordIdsQueryCondition.setOperator(IsfdMongoQueryOperatorEnum.INCLUDES.getValue());
            recordIdsQueryCondition.setValue(String.join(",", recordIds.stream()
                .map(String::valueOf)
                .collect(Collectors.joining(","))));
            recordIdsQueryCondition.setLogicalOperator(IsfdMongoQueryLogicalOperatorEnum.AND.getValue());
            mongoQuery.getConditions().add(recordIdsQueryCondition);
        }

        // 查询主数据
        List<Document> mainDataList = queryDataOfOneTableWithLogicDelete(mainTable.getTableName(), mongoQuery);

        dataTableMap.put(mainTable.getTableName(), mainDataList);
        // 获取完整数据列表
        if (queryCondition.isLoadCompleteRoute()) { // 是否加载完整树
            for (int i = fieldTableList.size() - 1; i >= 0; i--) {
                IsfdDatabaseModelConfigTableVo fieldTable = fieldTableList.get(i);
                List<Document> dataList = queryDataOfOneTableWithLogicDelete(fieldTable.getTableName(), new IsfdDatabaseMongoQuery());
                dataTableMap.put(fieldTable.getTableName(), dataList);
            }
        }

        // 递归所有数据
        List<Document> mergedData = new ArrayList<>(dataTableMap.get(mainTable.getTableName()));
        assert mergedData.size() == 1 : "主表数据必须只有一条，当前为：" + mergedData.size();

        // 深度
        int currentDepth = 1;
        int targetDepth = 1;
        if (queryCondition.isLoadCompleteRoute()) {
            targetDepth = 99;
        }

        // 递归数据
        List<Document> content = mergeDataRecursivelyAsTree(dataTableMap, mergedData, childTableNameMap, mainTable.getTableName(), treeDisplayFieldMap, currentDepth, targetDepth);

        // 构造返参
        IsfdDatabaseDataTreeResultVo treeResultVo = new IsfdDatabaseDataTreeResultVo();
        treeResultVo.setContent(content);

        // 是否有子表
        boolean hasChildren = fieldTableList.stream()
            .anyMatch(fieldTable ->
                fieldTable.getParentTableName().equals(mainTable.getTableName())
                    && (fieldTable.getShowType().equals(IsfdDatabaseModelShowTypeEnum.TREE.getValue())));
        treeResultVo.setHasChildren(hasChildren);

        // 设置父表信息
        treeResultVo.setParentId(parentId);

        // 分页信息
        long totalSize = queryDataCountOneTableWithLogicDelete(mainModel.getTableName(), mongoQuery);
        long pageSize = queryCondition.getPageSize();
        long pageNum = queryCondition.getPageNum();
        long totalPages = (totalSize + pageSize - 1) / pageSize;

        treeResultVo.setPageSize(pageSize);
        treeResultVo.setPageNum(pageNum);
        treeResultVo.setTotalSize(totalSize);
        treeResultVo.setTotalPages(totalPages);

        return treeResultVo;
    }

    private List<String> buildSearchFieldList(List<IsfdDatabaseModelConfigFieldVo> fieldVoList) {
        List<String> result = new ArrayList<>();
        for (IsfdDatabaseModelConfigFieldVo fieldVo : fieldVoList) {
            String fieldName = fieldVo.getFieldName();
            List<IsfdDatabaseModelConfigFieldVo> subFieldVoList = fieldVo.getFieldList();

            if (CollectionUtils.isEmpty(subFieldVoList)) {
                result.add(fieldName);
            }
            else {
                // 有子字段，递归生成子字段路径
                List<String> subFieldNames = buildSearchFieldList(subFieldVoList);
                for (String subFieldName : subFieldNames) {
                    result.add(fieldName + "." + subFieldName);
                }
            }
        }
        return  result;
    }

    private Map<String, Map<String, List<String>>> getTreeDisplayFieldMap(List<IsfdDatabaseModelConfigTableVo> fieldTableList) {
        Map<String, Map<String, List<String>>> treeDisplayMap = new LinkedHashMap<>();
        for (IsfdDatabaseModelConfigTableVo fieldTable : fieldTableList) {

            String parentTableName = fieldTable.getParentTableName();
            if (StringUtils.isNotBlank(parentTableName)) {
                IsfdDatabaseModelConfigTableVo parentTable = fieldTableList.stream()
                    .filter(vo -> vo.getTableName().equals(parentTableName))
                    .findFirst()
                    .orElse(null);
                if (parentTable != null) {
                    if (!parentTable.getShowType().equals(IsfdDatabaseModelShowTypeEnum.TREE.getValue()) &&
                        !fieldTable.getShowType().equals(IsfdDatabaseModelShowTypeEnum.TREE.getValue())) {
                        continue;
                    }
                }
            }

            Map<String, List<String>> fieldDisplayMap = new LinkedHashMap<>();
            String tableName = fieldTable.getTableName();
            List<IsfdDatabaseModelConfigFieldVo> fieldVoList = fieldTable.getFieldVoList();

            // 获取所有标记为 isTreeDisplayField == 1 的字段名
            List<String> treeDisplayFieldNames = fieldVoList.stream()
                .filter(vo -> vo.getIsTreeDisplayField() == 1)
                .map(IsfdDatabaseModelConfigFieldVo::getFieldName)
                .collect(Collectors.toList());

            if (treeDisplayFieldNames.isEmpty()) {
                treeDisplayFieldNames = Collections.singletonList(
                    IsfdDatabaseModelSpecialFieldNameEnum.OBJECT_ID.getValue()
                );
            }

            // 获取 children 字段名
            List<String> childrenDisplayFieldNames = new ArrayList<>();
            IsfdDatabaseModelConfigTableVo childTable = fieldTableList.stream()
                .filter(vo -> tableName.equals(vo.getParentTableName()))
                .findFirst()
                .orElse(null);

            if (childTable != null) {
                String parentFieldName = childTable.getParentFieldName();
                fieldVoList.stream()
                    .filter(vo -> vo.getFieldName().equals(parentFieldName))
                    .map(IsfdDatabaseModelConfigFieldVo::getFieldName)
                    .findFirst()
                    .ifPresent(childrenDisplayFieldNames::add);
            }

            fieldDisplayMap.put("data", treeDisplayFieldNames);
            fieldDisplayMap.put("children", childrenDisplayFieldNames);
            treeDisplayMap.put(tableName, fieldDisplayMap);
        }
        return treeDisplayMap;
    }

    private List<Document> mergeDataRecursivelyAsTree(Map<String, List<Document>> dataTableMap, List<Document> mergedData,
                                                      Map<String, String> childTableNameMap, String currentTableName,
                                                      Map<String, Map<String, List<String>>> treeDisplayFieldMap,
                                                      int currentDepth, int targetDepth) {

        if (currentDepth > targetDepth) {
            return new ArrayList<>();
        }

        for (int i = 0; i < mergedData.size(); i++) {

            Document document = mergedData.get(i);

            for (String key : document.keySet()) {
                String currentFieldName = currentTableName + "." + key;
                Object value = document.get(key);

                if (value == null) continue;

                // 检查字段是否是普通数据
                if (!(value instanceof List<?>)) {
                    continue;
                }

                // 判断是不是模型
                if (!childTableNameMap.containsKey(currentFieldName)) {
                    continue;
                }

                // 是模型
                @SuppressWarnings("unchecked")
                List<String> list = (List<String>) value;

                List<Object> relatedDataList = new ArrayList<>();

                for (String item : list) {
                    String tableName = childTableNameMap.get(currentFieldName);
                    String objectId = item;

                    // 查找对应表数据
                    List<Document> relatedData = dataTableMap.get(tableName);
                    if (relatedData == null) {
                        continue;
                    }

                    // 查找对应 objectId 的数据
                    for (Document relatedDocument : relatedData) {
                        if (objectId.equals(relatedDocument.get(IsfdDatabaseModelSpecialFieldNameEnum.OBJECT_ID.getValue()))) {
                            // 递归处理子表数据
                            List<Document> subList = new ArrayList<>();
                            subList.add(new Document(relatedDocument));
                            List<Document> wrappedSubList = mergeDataRecursivelyAsTree(dataTableMap, subList, childTableNameMap, tableName, treeDisplayFieldMap, currentDepth + 1, targetDepth);
                            if (!CollectionUtils.isEmpty(wrappedSubList) && wrappedSubList.size() == 1) {
                                Document subDoc = wrappedSubList.get(0);
                                Document detailData = new Document();
                                detailData.put("tableName", tableName);
                                detailData.put("objectId", objectId);
                                Set<String> currentChildTableNames = childTableNameMap.entrySet().stream()
                                    .filter(entry -> entry.getKey().contains(tableName))
                                    .map(Map.Entry::getValue)
                                    .collect(Collectors.toSet());
                                detailData.put("childTables", currentChildTableNames);
                                subDoc.put("detail", detailData);
                            }
                            relatedDataList.addAll(wrappedSubList);
                            break;
                        }
                    }
                }
                document.put(key, relatedDataList);
            }

            // 树结构展示字段
            Map<String, List<String>> displayFieldNames = treeDisplayFieldMap.get(currentTableName);
            if (CollectionUtils.isEmpty(displayFieldNames)) {
                return new ArrayList<>();
            }

            List<String> treeDisplayFieldNames = displayFieldNames.get("data");
            if (CollectionUtils.isEmpty(treeDisplayFieldNames)) {
                treeDisplayFieldNames = Collections.singletonList(IsfdDatabaseModelSpecialFieldNameEnum.OBJECT_ID.getValue());
            }

            String dataValue = treeDisplayFieldNames.stream()
                .flatMap(fieldName -> {
                    Object val = filterDocumentByKey(document, fieldName);
                    if (val == null) {
                        return Stream.empty();
                    }
                    if (val instanceof Document) {
                        // 对象类型，取所有键值的字符串
                        return ((Document) val).values().stream()
                            .filter(Objects::nonNull)
                            .map(Object::toString);
                    } else if (val instanceof List) {
                        // 列表类型，假设为 List<Document>，取每个文档的所有值
                        return ((List<?>) val).stream()
                            .filter(item -> item instanceof Document)
                            .flatMap(item -> ((Document) item).values().stream())
                            .filter(Objects::nonNull)
                            .map(Object::toString);
                    } else {
                        // 普通类型
                        return Stream.of(val.toString());
                    }
                })
                .filter(str -> !str.isEmpty())
                .collect(Collectors.joining(","));


            String childDisplayFieldName = "";
            List<String> childDisplayFieldNames = displayFieldNames.get("children");
            if (!CollectionUtils.isEmpty(childDisplayFieldNames)) {
                childDisplayFieldName = childDisplayFieldNames.get(0);
            }
            Object childrenValue = filterDocumentByKey(document, childDisplayFieldName);

            Document completeDocument = new Document();
            completeDocument.put("data", dataValue);
            completeDocument.put("children", childrenValue);

            Document detailData = new Document();
            detailData.put("tableName", currentTableName);
            detailData.put("objectId", filterDocumentByKey(document, IsfdDatabaseModelSpecialFieldNameEnum.OBJECT_ID.getValue()));
            Set<String> currentChildTableNames = childTableNameMap.entrySet().stream()
                .filter(entry -> entry.getKey().contains(currentTableName))
                .map(Map.Entry::getValue)
                .collect(Collectors.toSet());
            detailData.put("childTables", currentChildTableNames);
            completeDocument.put("detail", detailData);

            mergedData.set(i, completeDocument);
        }

        return mergedData;
    }

    @Override
    public PageResult<Object> queryDataTable(IsfdDatabaseDataTreeQueryBo queryCondition){
        Integer pageNum = queryCondition.getPageNum();
        Integer pageSize = queryCondition.getPageSize();

        // 以模型id为主. 找到主模型
        Long modelId = queryCondition.getModelId();
        String tableName = queryCondition.getTableName();
        IsfdDatabaseModelConfig mainModel = null;
        if (modelId != null) {
            mainModel = baseMapper.selectById(modelId);
        } else if (tableName != null) {
            mainModel = baseMapper.selectOne(new LambdaQueryWrapper<IsfdDatabaseModelConfig>()
                .eq(IsfdDatabaseModelConfig::getTableName, tableName));
        }

        if (mainModel == null) {
            throw new BaseException("没有找到关联模型");
        }

        // 拼接查询条件
        IsfdDatabaseMongoQuery mongoQuery = new IsfdDatabaseMongoQuery();
        mongoQuery.setConditions(new ArrayList<>());
        PageQuery pageQuery = new PageQuery();
        pageQuery.setPageSize(queryCondition.getPageSize());
        pageQuery.setPageNum(queryCondition.getPageNum());
        mongoQuery.setPageQuery(pageQuery);

        List<String> objectIds = Optional.ofNullable(queryCondition.getObjectIds())
            .orElse(Collections.emptyList())
            .stream()
            .filter(id -> id != null && !id.trim().isEmpty())
            .toList();
        if (!CollectionUtils.isEmpty(objectIds)) {
            IsfdDatabaseMongoQuery.IsfdDatabaseMongoQueryCondition objIdsQueryCondition = new IsfdDatabaseMongoQuery.IsfdDatabaseMongoQueryCondition();
            objIdsQueryCondition.setFieldName(IsfdDatabaseModelSpecialFieldNameEnum.OBJECT_ID.getValue());
            objIdsQueryCondition.setOperator(IsfdMongoQueryOperatorEnum.INCLUDES.getValue());
            objIdsQueryCondition.setValue(String.join(",", objectIds));
            objIdsQueryCondition.setLogicalOperator(IsfdMongoQueryLogicalOperatorEnum.AND.getValue());
            mongoQuery.getConditions().add(objIdsQueryCondition);
        }

        List<Long> recordIds = Optional.ofNullable(queryCondition.getImportRecordIds())
            .orElse(Collections.emptyList())
            .stream()
            .filter(Objects::nonNull)
            .toList();
        if (!CollectionUtils.isEmpty(recordIds)) {
            IsfdDatabaseMongoQuery.IsfdDatabaseMongoQueryCondition recordIdsQueryCondition = new IsfdDatabaseMongoQuery.IsfdDatabaseMongoQueryCondition();
            recordIdsQueryCondition.setFieldName(IsfdDatabaseModelSpecialFieldNameEnum.IMPORT_METHOD.getValue() + ".id");
            recordIdsQueryCondition.setOperator(IsfdMongoQueryOperatorEnum.INCLUDES.getValue());
            recordIdsQueryCondition.setValue(String.join(",", recordIds.stream()
                .map(String::valueOf)
                .collect(Collectors.joining(","))));
            recordIdsQueryCondition.setLogicalOperator(IsfdMongoQueryLogicalOperatorEnum.AND.getValue());
            mongoQuery.getConditions().add(recordIdsQueryCondition);
        }


        // 调用query
        List<Object> contentData = queryDataDetail(mainModel.getTableName(), null, mongoQuery);

        // 总量
        IsfdDatabaseMongoQuery countCondition = new IsfdDatabaseMongoQuery();
        // 增加逻辑删除筛选
        IsfdDatabaseMongoQuery.IsfdDatabaseMongoQueryCondition logicalDeleteQuery = new IsfdDatabaseMongoQuery.IsfdDatabaseMongoQueryCondition();
        logicalDeleteQuery.setFieldName(IsfdDatabaseModelSpecialFieldNameEnum.IMPORT_METHOD.getValue() + "." + "delete_flag");
        logicalDeleteQuery.setOperator("eq");
        logicalDeleteQuery.setValue("0");
        logicalDeleteQuery.setValueNumberCheck(true);
        countCondition.setConditions(new ArrayList<>());
        countCondition.getConditions().add(logicalDeleteQuery);
        Long totalCount = mongoService.count(mainModel.getTableName(), countCondition);

        PageResult<Object> result = new PageResult<>();
        result.setPageNum(pageNum);
        result.setPageSize(pageSize);
        result.setContentData(contentData);
        result.setTotalSize(totalCount);
        Long totalPages = (totalCount + pageSize - 1) / pageSize;
        result.setTotalPages(totalPages);
        return result;
    }

    private Document completeDataInfo(String key, Object data, String chinese, String type, String currentTableName, String currentObjectId) {

        if (chinese == null) {
            return null;
        }

        // 构造 Document 结果
        Document result = new Document();
        result.put("field", key);
        result.put("chinese", chinese); // 防止 `null`
        result.put("data", data);
        result.put("type", type);
        result.put("tableName", currentTableName);
        result.put("objectId", currentObjectId);
        return result;
    }

    private Object filterDocumentByKey(Document doc, String targetKey) {
        if (doc.containsKey(targetKey)) {
            return doc.get(targetKey);
        }
        return null;
    }

    @Override
    public String saveFileAndReturnAddress(String tableName, MultipartFile file) {
        String originalFilename = file.getOriginalFilename();
        if (originalFilename == null || !originalFilename.contains(".")) {
            throw new IllegalArgumentException("文件名无效，无法提取扩展名");
        }
        // 找出当前模型
        IsfdDatabaseModelConfig currentConfig = baseMapper.selectOne(new LambdaQueryWrapper<IsfdDatabaseModelConfig>()
            .eq(IsfdDatabaseModelConfig::getTableName, tableName));
        if (currentConfig == null) {
            throw new BaseException("找不到表：" + tableName);
        }
        // 找到根
        IsfdDatabaseModelConfig rootConfig = configService.queryByIdReturnTopParent(currentConfig.getId());
        if (rootConfig == null) {
            throw new BaseException("找不到父模型，model：" + currentConfig.getId());
        }
        String rootTableName = rootConfig.getTableName();
        // 生成目录
        Path targetDir = createTargetDir(rootTableName);
        Path filesDir = targetDir.resolve("files");

        // 保存文件
        return importDataFileStorageUtil.saveMultipartFile(filesDir, file).toString();
    }

    @Transactional(rollbackFor = Exception.class)
    public IsfdDatabaseExistDataInfo findAndDeleteExistingData(String tableName, List<String> objectIdStrs, List<IsfdDatabaseModelConfigTableVo> fieldTableList) {
        // 找到所有关联表及数据
        Map<String, List<Map<String, Object>>> existDataTableMap = new HashMap<>();
        Map<String, Map<String, Object>> currentImportRecords = findExistingData(tableName, objectIdStrs, fieldTableList, existDataTableMap);
        if (CollectionUtils.isEmpty(currentImportRecords)) {
            throw new BaseException("未找到导入记录字段！");
        }
        Long expectedId = null;
        for (Map<String, Object> importRecord : currentImportRecords.values()) {
            if (importRecord == null) continue;
            Object idObj = importRecord.get("id");
            if (!(idObj instanceof Number)) {
                throw new RuntimeException("importRecord缺少有效的id字段");
            }
            Long importId = ((Number) idObj).longValue();
            if (expectedId == null) {
                expectedId = importId;
            } else if (!expectedId.equals(importId)) {
                throw new RuntimeException("所有importId必须相同，发现不同的importId：" + importId + ", " + expectedId);
            }
        }
        Map<String, Object> currentImportRecord = currentImportRecords.values().iterator().next();


        // 删除关联数据
        Map<String, List<Map<String, Object>>> deletedDataMap = new HashMap<>();
        try {
            for (Map.Entry<String, List<Map<String, Object>>> entry : existDataTableMap.entrySet()) {
                String collection = entry.getKey();

                List<Map<String, Object>> existingDocuments = entry.getValue();
                List<String> ids = existingDocuments.stream()
                    .map(document -> (String) document.get(IsfdDatabaseModelSpecialFieldNameEnum.OBJECT_ID.getValue()))
                    .collect(Collectors.toList());

                mongoService.deleteByIds(collection, ids);
                deletedDataMap.put(collection, existingDocuments);
            }
        } catch (Exception e) {
            // 删除失败，重新插入数据
            if (!CollectionUtils.isEmpty(deletedDataMap)) {
                for (Map.Entry<String, List<Map<String, Object>>> entry : existDataTableMap.entrySet()) {
                    String collection = entry.getKey();
                    List<Map<String, Object>> deletedDocuments = entry.getValue();
                    mongoService.saveBatch(collection, deletedDocuments);
                }
            }
            log.error("关联数据删除失败: " + e.getMessage(), e);
            throw new BaseException("关联数据删除失败: " + e.getMessage());
        }

        // 构造返回参数
        IsfdDatabaseExistDataInfo existDataInfo = new IsfdDatabaseExistDataInfo();
        existDataInfo.setCurrentImportRecord(currentImportRecord);
        existDataInfo.setExistDataTableMap(existDataTableMap);
        return existDataInfo;
    }

    private Map<String, Map<String, Object>> findExistingData(String tableName, List<String> objectIdStrs, List<IsfdDatabaseModelConfigTableVo> fieldTableList, Map<String, List<Map<String, Object>>> existDocuments) {
        // 找到当前表数据
        List<Document> currentDatas = mongoService.findByIds(tableName, objectIdStrs);
        if (CollectionUtils.isEmpty(currentDatas)) {
            throw new BaseException("未找到相关数据！");
        }

        for (Document currentData : currentDatas) {
            String currentDataId = (String) currentData.get(IsfdDatabaseModelSpecialFieldNameEnum.OBJECT_ID.getValue());
            if(StringUtils.isBlank(currentDataId)) {
                throw new BaseException("数据没有_id!");
            }
            existDocuments.computeIfAbsent(tableName, k -> new ArrayList<>()).add(new HashMap<>(currentData));
            // 是否有子数据
            List<IsfdDatabaseModelConfigTableVo> childTableVos = fieldTableList.stream().filter(
                vo -> tableName.equals(vo.getParentTableName())
            ).toList();
            // 如果有
            if (!CollectionUtils.isEmpty(childTableVos)) {
                for (IsfdDatabaseModelConfigTableVo childTableVo : childTableVos) {
                    String childTableName = childTableVo.getTableName();
                    String parentFieldName = childTableVo.getParentFieldName();
                    @SuppressWarnings("unchecked")
                    List<String> childObjectIds = (List<String>) currentData.get(parentFieldName);
                    if (CollectionUtils.isEmpty(childObjectIds)) {
                        continue;
                    }
                    findExistingData(childTableName, childObjectIds, fieldTableList, existDocuments);
                }
            }

        }

        @SuppressWarnings("unchecked")
        Map<String, Map<String, Object>> currentImportRecords = currentDatas.stream()
            .filter(doc -> doc.get(IsfdDatabaseModelSpecialFieldNameEnum.IMPORT_METHOD.getValue()) instanceof Map)
            .collect(Collectors.toMap(
                doc -> doc.get(IsfdDatabaseModelSpecialFieldNameEnum.OBJECT_ID.getValue()).toString(),
                doc -> (Map<String, Object>) doc.get(IsfdDatabaseModelSpecialFieldNameEnum.IMPORT_METHOD.getValue())
            ));



        return currentImportRecords;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateData(String tableName, String objectIdStr, List<Object> data) {

        // 转为有效数据，并验证
        Map<String, Object> validatedData = extractValidFieldData(data, false, 0);
        if (CollectionUtils.isEmpty(validatedData)) {
            throw new BaseException("有效数据为空！");
        }
        return insertOrUpdateDataList(tableName, Collections.singletonList(validatedData), IsfdImportMethodEnum.SITE , null, true);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean insertData(String tableName, List<Object> data) {

        // 转为有效数据，并验证
        Map<String, Object> validatedData = extractValidFieldData(data, true, 0);
        if (CollectionUtils.isEmpty(validatedData)) {
            throw new BaseException("有效数据为空！");
        }
        return insertOrUpdateDataList(tableName, Collections.singletonList(validatedData), IsfdImportMethodEnum.SITE , null, false);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean insertOrUpdateDataList(String tableName, List<Map<String, Object>> structuredDataList, IsfdImportMethodEnum importMethod, IsfdDatabaseDataImportRecordBo recordBo, Boolean isUpdate) {
        if (recordBo == null) {
            recordBo = new IsfdDatabaseDataImportRecordBo();
        }
        // 找到模型
        IsfdDatabaseModelConfig modelConfig = baseMapper.selectOne(new LambdaQueryWrapper<IsfdDatabaseModelConfig>()
            .eq(IsfdDatabaseModelConfig::getTableName, tableName));
        if (modelConfig == null) {
            throw new BaseException("未找到关联模型！");
        }
        // 找到所有关联表
        List<IsfdDatabaseModelConfigTableVo> fieldTableList = configService.getFieldTableList(modelConfig.getId()); // 转换为列表

        IsfdDatabaseModelConfigTableVo currentTable =
            fieldTableList.stream()
                .filter(vo -> tableName.equals(vo.getTableName()))
                .findFirst()
                .orElseThrow(() -> new BaseException("未找到关联模型！"));

        Map<String, List<Map<String, Object>>> dataToBeInserted = new HashMap<>();
        Map<String, Integer> tableDataSizeMap = new HashMap<>();
        List<String> objectIdList = new ArrayList<>();
        for (Map<String, Object> structuredData : structuredDataList) {
            // 验证数据
            String objectId = (String) structuredData.get(IsfdDatabaseModelSpecialFieldNameEnum.OBJECT_ID.getValue());
            if (isUpdate && StringUtils.isBlank(objectId)) {
                throw new BaseException("数据更新，但数据中没有'_id'");
            }

            // 如果有父模型
            if (currentTable.getParentTableName() != null) {
                if (!structuredData.containsKey(IsfdDatabaseModelSpecialFieldNameEnum.PARENT_ID.getValue())) {
                    throw new BaseException("缺少parentId！");
                }
            }

            // 记录objectId
            String objectIdStr = StringUtils.isNotBlank(objectId) ? objectId : new ObjectId().toHexString();
            objectIdList.add(objectIdStr);
            Map<String, List<Map<String, Object>>> checkedData = checkImportData(structuredData, objectIdStr, fieldTableList, currentTable, null);

            // 统计数据量
            for (Map.Entry<String, List<Map<String, Object>>> entry : checkedData.entrySet()) {
                String table = entry.getKey();
                List<Map<String, Object>> datas = entry.getValue();
                if(!CollectionUtils.isEmpty(datas)) {
                    dataToBeInserted.computeIfAbsent(table, k -> new ArrayList<>()).addAll(datas);
                    tableDataSizeMap.put(table, tableDataSizeMap.getOrDefault(table, 0) + datas.size());
                }
            }
        }




        // 区分是新增还是更新
        IsfdDatabaseDataMongoImportRecordBo mongoImportRecord;
        Map<String, List<Map<String, Object>>> existingDataMap = null;
        IsfdDatabaseDataMongoImportRecordBo currentImportRecord = null;

        // 将导入记录记入数据，并重构数据
        try {
            // 生成mongo导入记录
            if (isUpdate) {
                // 找到并删除历史数据
                IsfdDatabaseExistDataInfo existDataInfo = findAndDeleteExistingData(tableName, objectIdList, fieldTableList);
                currentImportRecord = IsfdDatabaseDataMongoImportRecordBo.fromMap(existDataInfo.getCurrentImportRecord());
                existingDataMap = existDataInfo.getExistDataTableMap();
                // 生成导入记录
                mongoImportRecord = IsfdDatabaseDataMongoImportRecordBo.updateMongoImportRecord(currentImportRecord);
            } else {
                // 设置导入记录
                recordBo.setImportMethod(importMethod.getDesc());
                recordBo.setModelId(modelConfig.getId());
                recordBo.setModelName(modelConfig.getModelName());
                recordBo.setDataQuantity(objectIdList.size());
                recordBo.setTableName(String.join(",",dataToBeInserted.keySet()));

                // 生成导入记录
                IsfdDatabaseDataImportRecordBo importRecordBo = importRecordService.createImportRecord(recordBo, IsfdImportMethodEnum.SITE, tableName, tableDataSizeMap,  LoginHelper.getLoginUser());
                mongoImportRecord = IsfdDatabaseDataMongoImportRecordBo.createMongoImportRecord(importRecordBo);
            }

            // 获取数据变更并添加导入记录
            List<IsfdDatabaseDataAttachImportResult> dataChangeResult = attachImportRecords(dataToBeInserted, existingDataMap, mongoImportRecord);

            if (isUpdate) {
                // 更新数据导入记录子表
                for (IsfdDatabaseDataAttachImportResult dataChange : dataChangeResult) {
                    importRecordService.updateOrCreateImportSubRecord(mongoImportRecord.getId(), dataChange.getTableName(),
                        dataChange.getCreatedCount(), dataChange.getDeletedCount(), dataChange.getExistedCount());
                }
            }

            // 导入数据
            Map<String, List<Map<String, Object>>> finalData = new HashMap<>();
            for (IsfdDatabaseDataAttachImportResult data : dataChangeResult) {
                finalData.put(data.getTableName(), data.getData()); // 这里提取每个表对应的数据列表
            }
            importData(finalData, mongoImportRecord, null, modelConfig.getId());

        } catch (Exception e) {
            // 如果报错重新导入原来的数据
            if (isUpdate) {
                try {
                    importData(existingDataMap, currentImportRecord, null, modelConfig.getId());
                } catch (Exception rollbackEx) {
                    log.error("更新失败且回滚失败，原始错误: {}, 回滚错误: {}", e.getMessage(), rollbackEx.getMessage());
                    throw new BaseException("更新失败，且回滚失败！");
                }
            }
            log.error("数据插入失败！message: " + e.getMessage());
            throw new BaseException("数据插入失败！message: " + e.getMessage());
        }

        return true;
    }

    @SuppressWarnings("unchecked")
    private Map<String, Object> extractValidFieldData(List<Object> input, Boolean filterInfo, int depth) {
        Map<String, Object> result = new HashMap<>();
        for (Object obj : input) {
            if (!(obj instanceof Map)) continue;
            Map<String, Object> map = (Map<String, Object>) obj;

            // 必须包含这几个 key
            if (!map.keySet().containsAll(Set.of("field", "chinese", "data", "type"))) {
                throw new BaseException("返回数据格式存在问题！");
            }

            String field = (String) map.get("field");
            String type = (String) map.get("type");
            Object data = map.get("data");

            // 如果要过滤信息
            if (field.equals(IsfdDatabaseModelSpecialFieldNameEnum.OBJECT_ID.getValue()) && filterInfo) {
                continue;
            }
            // 去掉子层的parentId
            if (field.equals(IsfdDatabaseModelSpecialFieldNameEnum.PARENT_ID.getValue())) {
                if (filterInfo && depth > 0) {
                    continue;
                }
            }

            if ("object".equals(type) && data instanceof List) {
                result.put(field, extractValidFieldData((List<Object>) data, filterInfo, depth + 1));
            }

            else if ("table".equals(type) && data instanceof List) {
                List<List<Object>> tableDataList = (List<List<Object>>) data;
                List<Map<String, Object>> subDataList = new ArrayList<>();
                for (List<Object> tableData : tableDataList) {
                    Map<String, Object> childDataMap = extractValidFieldData(tableData, filterInfo, depth + 1);
                    subDataList.add(childDataMap);
                }
                result.put(field, subDataList);
            }

            else {
                result.put(field, data);
            }
        }
        return result;
    }

    private Document updateParentData(String parentTableName, String parentFieldName, String parentId, List<String> objectIdStrs) {
        // 如果有父模型
        Document originalParentData;
        if (StringUtils.isBlank(parentTableName)) {
            throw new BaseException("未找到关联的父模型！");
        }
        if (StringUtils.isBlank(parentId)) {
            throw new BaseException("数据未关联到父模型数据！");
        }
        // 找到父模型数据
        Document parentData = mongoService.findById(parentTableName, parentId);
        if (parentData == null) {
            throw new BaseException("未找到父模型数据！table: " + parentTableName + ", id: " + parentId);
        }
        originalParentData = Document.parse(parentData.toJson());
        // 找到关联字段
        Object parentField = parentData.get(parentFieldName);
        if (!(parentField instanceof List<?>)) throw new BaseException("父模型数据有误！table: " + parentTableName + ", id: " + parentId);
        @SuppressWarnings("unchecked")
        List<String> parentFieldData = (List<String>) parentField;
        Set<String> mergedSet = new LinkedHashSet<>(parentFieldData);
        mergedSet.addAll(objectIdStrs);
        parentData.put(parentFieldName, new ArrayList<>(mergedSet));

        // 更新导入记录
        @SuppressWarnings("unchecked")
        IsfdDatabaseDataMongoImportRecordBo importRecord = IsfdDatabaseDataMongoImportRecordBo.fromMap(
            (Map<String, Object>) parentData.get(IsfdDatabaseModelSpecialFieldNameEnum.IMPORT_METHOD.getValue()));
        IsfdDatabaseDataMongoImportRecordBo updatedImportRecord = IsfdDatabaseDataMongoImportRecordBo.updateMongoImportRecord(importRecord);
        parentData.put(IsfdDatabaseModelSpecialFieldNameEnum.IMPORT_METHOD.getValue(), updatedImportRecord.toMap());

        // 更新数据
        mongoService.updateById(parentTableName, parentId, parentData);
        return originalParentData;
    }

    @Override
    public Boolean deleteDataByRecordId(Long recordId) {
        IsfdDatabaseDataImportRecordVo recordVo = importRecordService.queryById(recordId);
        assert recordVo != null;
        Long modelId = recordVo.getModelId();
        List<String> tableNameList = configService.getFieldTableList(modelId).stream()
            .map(IsfdDatabaseModelConfigTableVo::getTableName) // 提取表名
            .toList(); // 转换为列表
        if (CollectionUtils.isEmpty(tableNameList)) {
            throw new BaseException("未找到匹配的表！");
        }
        for (String tableName : tableNameList) {
            Map<String, Object> deleteData = new HashMap<>();
            deleteData.put("importRecord.id", recordId);
            mongoService.delete(tableName, deleteData);
        }
        return true;
    }

    public static class DataCheckFailedException extends BaseException {
        public DataCheckFailedException(String message) {
            super(message);
        }
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean logicDeleteData(String tableName, String objectIdStr) {
        // 找到关联模型
        IsfdDatabaseModelConfig currentConfig = baseMapper.selectOne(
            new LambdaQueryWrapper<IsfdDatabaseModelConfig>()
                .eq(IsfdDatabaseModelConfig::getTableName, tableName)
        );
        if (currentConfig == null) {
            throw new BaseException("没有找到关联模型！");
        }
        // 所有子表
        List<IsfdDatabaseModelConfigTableVo> fieldTableList = configService.getFieldTableList(currentConfig.getId());
        if (CollectionUtils.isEmpty(fieldTableList)) {
            throw new BaseException("没有找到关联模型！");
        }
        Map<String, IsfdDatabaseModelConfigTableVo> fieldTableMap = fieldTableList.stream()
            .filter(vo -> StringUtils.isNotBlank(vo.getParentTableName()) && StringUtils.isNotBlank(vo.getParentFieldName()))
            .collect(Collectors.toMap(
                vo -> vo.getParentTableName() + '.' + vo.getParentFieldName(),
                Function.identity(),
                (v1, v2) -> {
                    throw new BaseException("重复字段!");
                }
            ));

        // 更新数据
        updateDeleteFlagData(tableName, objectIdStr, fieldTableMap, 1);
        return true;
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean recoverLogicDeleteData(String tableName, String objectIdStr) {
        // 找到关联模型
        IsfdDatabaseModelConfig currentConfig = baseMapper.selectOne(
            new LambdaQueryWrapper<IsfdDatabaseModelConfig>()
                .eq(IsfdDatabaseModelConfig::getTableName, tableName)
        );
        if (currentConfig == null) {
            throw new BaseException("没有找到关联模型！");
        }
        // 所有子表
        List<IsfdDatabaseModelConfigTableVo> fieldTableList = configService.getFieldTableList(currentConfig.getId());
        if (CollectionUtils.isEmpty(fieldTableList)) {
            throw new BaseException("没有找到关联模型！");
        }
        Map<String, IsfdDatabaseModelConfigTableVo> fieldTableMap = fieldTableList.stream()
            .filter(vo -> StringUtils.isNotBlank(vo.getParentTableName()) && StringUtils.isNotBlank(vo.getParentFieldName()))
            .collect(Collectors.toMap(
                vo -> vo.getParentTableName() + '.' + vo.getParentFieldName(),
                Function.identity(),
                (v1, v2) -> {
                    throw new BaseException("重复字段!");
                }
            ));

        // 更新数据
        updateDeleteFlagData(tableName, objectIdStr, fieldTableMap, 0);
        return true;
    }

    @Transactional(rollbackFor = Exception.class)
    public void updateDeleteFlagData(String tableName, String objectIdStr, Map<String, IsfdDatabaseModelConfigTableVo> fieldTableMap, Integer value) {
        // 找到当前数据
        Document currentData = mongoService.findById(tableName, objectIdStr);
        if (currentData == null) {
            throw new BaseException("未找到相关数据！");
        }
        // 找到导入记录
        @SuppressWarnings("unchecked")
        IsfdDatabaseDataMongoImportRecordBo currentImportRecord = IsfdDatabaseDataMongoImportRecordBo.fromMap(
            (Map<String, Object>) currentData.get(IsfdDatabaseModelSpecialFieldNameEnum.IMPORT_METHOD.getValue()));
        if (currentImportRecord == null) {
            throw new BaseException("未找到数据导入记录！");
        }
        // 更新数据标识
        IsfdDatabaseDataMongoImportRecordBo logicalDeleteImportRecord = IsfdDatabaseDataMongoImportRecordBo.updateMongoImportRecordDeleteFlag(currentImportRecord, value);
        currentData.put(IsfdDatabaseModelSpecialFieldNameEnum.IMPORT_METHOD.getValue(), logicalDeleteImportRecord.toMap());

        // 查找是否有子数据
        for (String fieldName : currentData.keySet()) {
            String fieldKey = tableName + "." + fieldName;

            if (!fieldTableMap.containsKey(fieldKey)) {
                continue;
            }
            IsfdDatabaseModelConfigTableVo fieldTable = fieldTableMap.get(fieldKey);
            String childTableName = fieldTable.getTableName();
            // 如果有子数据
            @SuppressWarnings("unchecked")
            List<String> childObjIds = (List<String>) currentData.get(fieldName);
            if (CollectionUtils.isEmpty(childObjIds)) {
                continue;
            }
            for (String childObjId : childObjIds) {
                updateDeleteFlagData(childTableName, childObjId, fieldTableMap, value);
            }
        }

        // 更新当前数据
        mongoService.updateById(tableName, objectIdStr, currentData);

        // 更新记录
        boolean isDelete = (value == 1);
        int createCount = isDelete ? 0 : 1;
        int deleteCount = isDelete ? 1 : 0;
        importRecordService.updateOrCreateImportSubRecord(currentImportRecord.getId(), tableName, createCount, deleteCount, 0);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean clearDataByModelId(Long modelId, Long recordId) {
        // 验证是主模型
        IsfdDatabaseModelConfig rootModel = baseMapper.selectById(modelId);
        if (rootModel == null) {
            throw new BaseException("未找到模型！");
        }
        if (rootModel.getParentConfigId() != null) {
            throw new BaseException("不是根模型，不能清除数据！");
        }

        // 如果有导入记录id筛选
        if (recordId != null) {
            IsfdDatabaseMongoQuery.IsfdDatabaseMongoQueryCondition logicalDeleteQuery = new IsfdDatabaseMongoQuery.IsfdDatabaseMongoQueryCondition();
            logicalDeleteQuery.setFieldName(IsfdDatabaseModelSpecialFieldNameEnum.IMPORT_METHOD.getValue() + "." + "id");
            logicalDeleteQuery.setOperator("eq");
            logicalDeleteQuery.setValue(recordId.toString());
            logicalDeleteQuery.setValueNumberCheck(true);
        }

        // 找到导入记录
        IsfdDatabaseDataImportRecordBo queryRecordBo = new IsfdDatabaseDataImportRecordBo();
        queryRecordBo.setModelId(rootModel.getId());
        queryRecordBo.setIsDelete(0L);
        if (recordId != null) {
            queryRecordBo.setId(recordId);
        }
        List<IsfdDatabaseDataImportRecordVo> recordVos = importRecordService.queryList(queryRecordBo);
        // 清除导入记录
        if (!CollectionUtils.isEmpty(recordVos)) {
            List<Long> recordIds = recordVos.stream()
                .map(IsfdDatabaseDataImportRecordVo::getId) // 提取 ID
                .toList();
            importRecordService.deletByIds(recordIds);
        }

        // 找到所有关联表格
        List<IsfdDatabaseModelConfigTableVo> fieldTableList = configService.getFieldTableList(modelId);
        if (CollectionUtils.isEmpty(fieldTableList)) {
            throw new BaseException("未找到关联模型！");
        }

        List<String> relatedTableNames = fieldTableList.stream().map(
            IsfdDatabaseModelConfigTableVo::getTableName
        ).toList();

        // 清空数据
        Map<String, List<Document>> deletedDataMap = new HashMap<>();
        for (String tableName : relatedTableNames) {
            List<Document> data = mongoService.findAll(tableName);
            if (CollectionUtils.isEmpty(data)) {
                continue;
            }
            try {
                mongoService.clearCollection(tableName);

                deletedDataMap.put(tableName, data);

            } catch (Exception e) {
                // 重新插入数据
                if (!CollectionUtils.isEmpty(deletedDataMap.get(tableName))) {
                    for (String key : deletedDataMap.keySet()) {
                        List<Document> values = deletedDataMap.get(key);
                        List<Map<String, Object>> mapList = values.stream()
                            .map(doc -> new HashMap<>(doc)) // 或者 (Map<String, Object>) doc
                            .collect(Collectors.toList());
                        mongoService.saveBatch(key, mapList);
                    }
                }
                throw new BaseException("模型数据清空失败！");
            }
        }

        return true;
    }

}
